/*
 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/core/editing/frame_caret.h"

#include "base/location.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/editing/caret_display_item_client.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/local_caret_rect.h"
#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
#include "third_party/blink/renderer/core/editing/selection_editor.h"
#include "third_party/blink/renderer/core/editing/visible_position.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/page/page.h"

namespace blink {

FrameCaret::FrameCaret(LocalFrame& frame,
                       const SelectionEditor& selection_editor)
    : selection_editor_(&selection_editor),
      frame_(frame),
      display_item_client_(new CaretDisplayItemClient()),
      caret_blink_timer_(frame.GetTaskRunner(TaskType::kInternalDefault),
                         this,
                         &FrameCaret::CaretBlinkTimerFired) {}

FrameCaret::~FrameCaret() = default;

void FrameCaret::Trace(Visitor* visitor) const {
  visitor->Trace(selection_editor_);
  visitor->Trace(frame_);
  visitor->Trace(caret_blink_timer_);
}

const PositionWithAffinity FrameCaret::CaretPosition() const {
  const VisibleSelection& selection =
      selection_editor_->ComputeVisibleSelectionInDOMTree();
  if (!selection.IsCaret())
    return PositionWithAffinity();
  DCHECK(selection.Start().IsValidFor(*frame_->GetDocument()));
  return PositionWithAffinity(selection.Start(), selection.Affinity());
}

bool FrameCaret::IsActive() const {
  return CaretPosition().IsNotNull();
}

void FrameCaret::UpdateAppearance() {
  DCHECK_GE(frame_->GetDocument()->Lifecycle().GetState(),
            DocumentLifecycle::kLayoutClean);
  // Paint a block cursor instead of a caret in overtype mode unless the caret
  // is at the end of a line (in this case the FrameSelection will paint a
  // blinking caret as usual).
  const bool paint_block_cursor =
      should_show_block_cursor_ && IsActive() &&
      !IsLogicalEndOfLine(CreateVisiblePosition(CaretPosition()));

  bool new_should_show_caret = ShouldShowCaret();
  if (new_should_show_caret != should_show_caret_) {
    should_show_caret_ = new_should_show_caret;
    ScheduleVisualUpdateForPaintInvalidationIfNeeded();
  }

  bool should_blink = !paint_block_cursor && should_show_caret_;
  if (!should_blink) {
    StopCaretBlinkTimer();
    return;
  }
  // Start blinking with a black caret. Be sure not to restart if we're
  // already blinking in the right location.
  StartBlinkCaret();
}

void FrameCaret::StopCaretBlinkTimer() {
  if (caret_blink_timer_.IsActive() ||
      display_item_client_->IsVisibleIfActive())
    ScheduleVisualUpdateForPaintInvalidationIfNeeded();
  display_item_client_->SetVisibleIfActive(false);
  caret_blink_timer_.Stop();
}

void FrameCaret::StartBlinkCaret() {
  // Start blinking with a black caret. Be sure not to restart if we're
  // already blinking in the right location.
  if (caret_blink_timer_.IsActive())
    return;

  base::TimeDelta blink_interval = LayoutTheme::GetTheme().CaretBlinkInterval();
  if (!blink_interval.is_zero())
    caret_blink_timer_.StartRepeating(blink_interval, FROM_HERE);

  display_item_client_->SetVisibleIfActive(true);
  ScheduleVisualUpdateForPaintInvalidationIfNeeded();
}

void FrameCaret::SetCaretEnabled(bool enabled) {
  if (is_caret_enabled_ == enabled)
    return;

  is_caret_enabled_ = enabled;

  if (!is_caret_enabled_)
    StopCaretBlinkTimer();
  ScheduleVisualUpdateForPaintInvalidationIfNeeded();
}

void FrameCaret::LayoutBlockWillBeDestroyed(const LayoutBlock& block) {
  display_item_client_->LayoutBlockWillBeDestroyed(block);
}

void FrameCaret::UpdateStyleAndLayoutIfNeeded() {
  DCHECK_GE(frame_->GetDocument()->Lifecycle().GetState(),
            DocumentLifecycle::kLayoutClean);
  UpdateAppearance();
  display_item_client_->UpdateStyleAndLayoutIfNeeded(
      should_show_caret_ ? CaretPosition() : PositionWithAffinity());
}

void FrameCaret::InvalidatePaint(const LayoutBlock& block,
                                 const PaintInvalidatorContext& context) {
  display_item_client_->InvalidatePaint(block, context);
}

IntRect FrameCaret::AbsoluteCaretBounds() const {
  DCHECK_NE(frame_->GetDocument()->Lifecycle().GetState(),
            DocumentLifecycle::kInPrePaint);
  DCHECK(!frame_->GetDocument()->NeedsLayoutTreeUpdate());
  DocumentLifecycle::DisallowTransitionScope disallow_transition(
      frame_->GetDocument()->Lifecycle());

  return AbsoluteCaretBoundsOf(CaretPosition());
}

void FrameCaret::SetShouldShowBlockCursor(bool should_show_block_cursor) {
  should_show_block_cursor_ = should_show_block_cursor;
  ScheduleVisualUpdateForPaintInvalidationIfNeeded();
}

bool FrameCaret::ShouldPaintCaret(const LayoutBlock& block) const {
  return display_item_client_->ShouldPaintCaret(block);
}

void FrameCaret::PaintCaret(GraphicsContext& context,
                            const PhysicalOffset& paint_offset) const {
  display_item_client_->PaintCaret(context, paint_offset, DisplayItem::kCaret);
  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
      frame_->Selection().IsHandleVisible() && !frame_->Selection().IsHidden())
    display_item_client_->RecordSelection(context, paint_offset);
}

bool FrameCaret::ShouldShowCaret() const {
  // Don't show the caret if it isn't visible or positioned.
  if (!is_caret_enabled_ || !IsActive())
    return false;

  Element* root = RootEditableElementOf(CaretPosition().GetPosition());
  if (root) {
    // Caret is contained in editable content. If there is no focused element,
    // don't show the caret.
    Element* focused_element = root->GetDocument().FocusedElement();
    if (!focused_element)
      return false;
  } else {
    // Caret is not contained in editable content--see if caret browsing is
    // enabled. If it isn't, don't show the caret.
    if (!frame_->IsCaretBrowsingEnabled())
      return false;
  }

  if (!IsEditablePosition(
          selection_editor_->ComputeVisibleSelectionInDOMTree().Start()) &&
      !frame_->IsCaretBrowsingEnabled())
    return false;

  // Only show the caret if the selection has focus.
  return frame_->Selection().SelectionHasFocus();
}

void FrameCaret::CaretBlinkTimerFired(TimerBase*) {
  DCHECK(is_caret_enabled_);
  if (IsCaretBlinkingSuspended() && display_item_client_->IsVisibleIfActive())
    return;
  display_item_client_->SetVisibleIfActive(
      !display_item_client_->IsVisibleIfActive());
  ScheduleVisualUpdateForPaintInvalidationIfNeeded();
}

void FrameCaret::ScheduleVisualUpdateForPaintInvalidationIfNeeded() {
  if (LocalFrameView* frame_view = frame_->View())
    frame_view->ScheduleVisualUpdateForPaintInvalidationIfNeeded();
}

void FrameCaret::RecreateCaretBlinkTimerForTesting(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  caret_blink_timer_.MoveToNewTaskRunner(std::move(task_runner));
}

bool FrameCaret::IsVisibleIfActiveForTesting() const {
  return display_item_client_->IsVisibleIfActive();
}

}  // namespace blink
