// Copyright 2017 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.

#include "core/editing/markers/TextMatchMarkerListImpl.h"

#include "core/dom/Node.h"
#include "core/dom/Range.h"
#include "core/editing/EphemeralRange.h"
#include "core/editing/markers/DocumentMarkerListEditor.h"
#include "core/editing/markers/TextMatchMarker.h"
#include "third_party/WebKit/Source/core/editing/VisibleUnits.h"

namespace blink {

DocumentMarker::MarkerType TextMatchMarkerListImpl::MarkerType() const {
  return DocumentMarker::kTextMatch;
}

bool TextMatchMarkerListImpl::IsEmpty() const {
  return markers_.IsEmpty();
}

void TextMatchMarkerListImpl::Add(DocumentMarker* marker) {
  DocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping(
      &markers_, TextMatchMarker::Create(*marker));
}

void TextMatchMarkerListImpl::Clear() {
  markers_.clear();
}

const HeapVector<Member<DocumentMarker>>& TextMatchMarkerListImpl::GetMarkers()
    const {
  return markers_;
}

bool TextMatchMarkerListImpl::MoveMarkers(int length,
                                          DocumentMarkerList* dst_list) {
  return DocumentMarkerListEditor::MoveMarkers(&markers_, length, dst_list);
}

bool TextMatchMarkerListImpl::RemoveMarkers(unsigned start_offset, int length) {
  return DocumentMarkerListEditor::RemoveMarkers(&markers_, start_offset,
                                                 length);
}

bool TextMatchMarkerListImpl::ShiftMarkers(unsigned offset,
                                           unsigned old_length,
                                           unsigned new_length) {
  return DocumentMarkerListEditor::ShiftMarkersContentDependent(
      &markers_, offset, old_length, new_length);
}

DEFINE_TRACE(TextMatchMarkerListImpl) {
  visitor->Trace(markers_);
  DocumentMarkerList::Trace(visitor);
}

static void UpdateMarkerRenderedRect(const Node& node,
                                     TextMatchMarker& marker) {
  const Position start_position(&const_cast<Node&>(node), marker.StartOffset());
  const Position end_position(&const_cast<Node&>(node), marker.EndOffset());
  EphemeralRange range(start_position, end_position);
  marker.SetRenderedRect(LayoutRect(ComputeTextRect(range)));
}

Vector<IntRect> TextMatchMarkerListImpl::RenderedRects(const Node& node) const {
  Vector<IntRect> result;

  for (DocumentMarker* marker : markers_) {
    TextMatchMarker* const text_match_marker = ToTextMatchMarker(marker);
    if (!text_match_marker->IsValid())
      UpdateMarkerRenderedRect(node, *text_match_marker);
    if (!text_match_marker->IsRendered())
      continue;
    result.push_back(text_match_marker->RenderedRect());
  }

  return result;
}

bool TextMatchMarkerListImpl::SetTextMatchMarkersActive(unsigned start_offset,
                                                        unsigned end_offset,
                                                        bool active) {
  bool doc_dirty = false;
  const auto start = std::upper_bound(
      markers_.begin(), markers_.end(), start_offset,
      [](size_t start_offset, const Member<DocumentMarker>& marker) {
        return start_offset < marker->EndOffset();
      });
  for (auto it = start; it != markers_.end(); ++it) {
    DocumentMarker& marker = **it;
    // Markers are returned in order, so stop if we are now past the specified
    // range.
    if (marker.StartOffset() >= end_offset)
      break;
    marker.SetIsActiveMatch(active);
    doc_dirty = true;
  }
  return doc_dirty;
}

}  // namespace blink
