// Copyright 2016 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 "third_party/blink/renderer/core/intersection_observer/intersection_geometry.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/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"

namespace blink {

namespace {

bool IsContainingBlockChainDescendant(LayoutObject* descendant,
                                      LayoutObject* ancestor) {
  LocalFrame* ancestor_frame = ancestor->GetDocument().GetFrame();
  LocalFrame* descendant_frame = descendant->GetDocument().GetFrame();
  if (ancestor_frame != descendant_frame)
    return false;

  while (descendant && descendant != ancestor)
    descendant = descendant->ContainingBlock();
  return descendant;
}

void MapRectUpToDocument(LayoutRect& rect, const LayoutObject& descendant) {
  FloatQuad mapped_quad =
      descendant.LocalToAncestorQuad(FloatQuad(FloatRect(rect)), nullptr,
                                     kUseTransforms | kApplyContainerFlip);
  rect = LayoutRect(mapped_quad.BoundingBox());
}

void MapRectDownToDocument(LayoutRect& rect,
                           const Document& document) {
  FloatQuad mapped_quad = document.GetLayoutView()->AncestorToLocalQuad(
      nullptr, FloatQuad(FloatRect(rect)),
      kUseTransforms | kApplyContainerFlip | kTraverseDocumentBoundaries);
  rect = LayoutRect(mapped_quad.BoundingBox());
}

LayoutUnit ComputeMargin(const Length& length, LayoutUnit reference_length) {
  if (length.IsPercent()) {
    return LayoutUnit(static_cast<int>(reference_length.ToFloat() *
                                       length.Percent() / 100.0));
  }
  DCHECK(length.IsFixed());
  return LayoutUnit(length.IntValue());
}

LayoutView* LocalRootView(Element& element) {
  LocalFrame* frame = element.GetDocument().GetFrame();
  LocalFrame* frame_root = frame ? &frame->LocalFrameRoot() : nullptr;
  return frame_root ? frame_root->ContentLayoutObject() : nullptr;
}

bool ComputeIsVisible(LayoutObject* target, const LayoutRect& rect) {
  DCHECK(RuntimeEnabledFeatures::IntersectionObserverV2Enabled());
  if (target->GetDocument().GetFrame()->LocalFrameRoot().GetOcclusionState() !=
      FrameOcclusionState::kGuaranteedNotOccluded) {
    return false;
  }
  if (target->HasDistortingVisualEffects())
    return false;
  // TODO(layout-dev): This should hit-test the intersection rect, not the
  // target rect; it's not helpful to know that the portion of the target that
  // is clipped is also occluded.
  HitTestResult result(target->HitTestForOcclusion(rect));
  return (!result.InnerNode() || result.InnerNode() == target->GetNode());
}

static const unsigned kConstructorFlagsMask =
    IntersectionGeometry::kShouldReportRootBounds |
    IntersectionGeometry::kShouldComputeVisibility |
    IntersectionGeometry::kShouldTrackFractionOfRoot |
    IntersectionGeometry::kShouldUseReplacedContentRect |
    IntersectionGeometry::kShouldConvertToCSSPixels;

}  // namespace

IntersectionGeometry::IntersectionGeometry(Element* root_element,
                                           Element& target_element,
                                           const Vector<Length>& root_margin,
                                           const Vector<float>& thresholds,
                                           unsigned flags)
    : flags_(flags & kConstructorFlagsMask),
      intersection_ratio_(0),
      threshold_index_(0) {
  DCHECK(root_margin.IsEmpty() || root_margin.size() == 4);
  ComputeGeometry(root_element, target_element, root_margin, thresholds);
}

IntersectionGeometry::~IntersectionGeometry() = default;

void IntersectionGeometry::ComputeGeometry(Element* root_element,
                                           Element& target_element,
                                           const Vector<Length>& root_margin,
                                           const Vector<float>& thresholds) {
  LayoutObject* target = target_element.GetLayoutObject();
  LayoutObject* root;
  if (root_element) {
    root = root_element->GetLayoutObject();
    flags_ &= ~kRootIsImplicit;
  } else {
    root = LocalRootView(target_element);
    flags_ |= kRootIsImplicit;
  }
  if (!target_element.isConnected())
    return;
  if (root_element && !root_element->isConnected())
    return;
  if (!root || !root->IsBox())
    return;
  if (!target || (!target->IsBoxModelObject() && !target->IsText()))
    return;
  if (root_element && !IsContainingBlockChainDescendant(target, root))
    return;

  DCHECK(!target_element.GetDocument().View()->NeedsLayout());

  target_rect_ = InitializeTargetRect(target);
  intersection_rect_ = target_rect_;
  root_rect_ = InitializeRootRect(root, root_margin);
  bool does_intersect =
      ClipToRoot(root, target, root_rect_, intersection_rect_);
  MapRectUpToDocument(target_rect_, *target);
  if (does_intersect) {
    if (RootIsImplicit())
      MapRectDownToDocument(intersection_rect_, target->GetDocument());
    else
      MapRectUpToDocument(intersection_rect_, *root);
  } else {
    intersection_rect_ = LayoutRect();
  }
  MapRectUpToDocument(root_rect_, *root);

  // Some corner cases for threshold index:
  //   - If target rect is zero area, because it has zero width and/or zero
  //     height,
  //     only two states are recognized:
  //     - 0 means not intersecting.
  //     - 1 means intersecting.
  //     No other threshold crossings are possible.
  //   - Otherwise:
  //     - If root and target do not intersect, the threshold index is 0.

  //     - If root and target intersect but the intersection has zero-area
  //       (i.e., they have a coincident edge or corner), we consider the
  //       intersection to have "crossed" a zero threshold, but not crossed
  //       any non-zero threshold.

  if (does_intersect) {
    const LayoutRect comparison_rect =
        ShouldTrackFractionOfRoot() ? root_rect_ : target_rect_;
    if (comparison_rect.IsEmpty()) {
      intersection_ratio_ = 1;
    } else {
      const LayoutSize& intersection_size = intersection_rect_.Size();
      const float intersection_area = intersection_size.Width().ToFloat() *
                                      intersection_size.Height().ToFloat();
      const LayoutSize& comparison_size = comparison_rect.Size();
      const float area_of_interest = comparison_size.Width().ToFloat() *
                                     comparison_size.Height().ToFloat();
      intersection_ratio_ = intersection_area / area_of_interest;
    }
    threshold_index_ =
        FirstThresholdGreaterThan(intersection_ratio_, thresholds);
  } else {
    intersection_ratio_ = 0;
    threshold_index_ = 0;
  }
  if (IsIntersecting() && ShouldComputeVisibility() &&
      ComputeIsVisible(target, target_rect_))
    flags_ |= kIsVisible;

  if (flags_ & kShouldConvertToCSSPixels) {
    FloatRect target_float_rect(target_rect_);
    AdjustForAbsoluteZoom::AdjustFloatRect(target_float_rect, *target);
    target_rect_ = LayoutRect(target_float_rect);
    FloatRect intersection_float_rect(intersection_rect_);
    AdjustForAbsoluteZoom::AdjustFloatRect(intersection_float_rect, *target);
    intersection_rect_ = LayoutRect(intersection_float_rect);
    FloatRect root_float_rect(root_rect_);
    AdjustForAbsoluteZoom::AdjustFloatRect(root_float_rect, *root);
    root_rect_ = LayoutRect(root_float_rect);
  }
}

LayoutRect IntersectionGeometry::InitializeTargetRect(LayoutObject* target) {
  if ((flags_ & kShouldUseReplacedContentRect) &&
      target->IsLayoutEmbeddedContent()) {
    return ToLayoutEmbeddedContent(target)->ReplacedContentRect();
  }
  if (target->IsBox())
    return LayoutRect(ToLayoutBoxModelObject(target)->BorderBoundingBox());
  if (target->IsLayoutInline())
    return ToLayoutInline(target)->LinesBoundingBox();
  return ToLayoutText(target)->LinesBoundingBox();
}

LayoutRect IntersectionGeometry::InitializeRootRect(
    LayoutObject* root,
    const Vector<Length>& margin) {
  LayoutRect result;
  if (root->IsLayoutView() && root->GetDocument().IsInMainFrame()) {
    // The main frame is a bit special as the scrolling viewport can differ in
    // size from the LayoutView itself. There's two situations this occurs in:
    // 1) The ForceZeroLayoutHeight quirk setting is used in Android WebView for
    // compatibility and sets the initial-containing-block's (a.k.a.
    // LayoutView) height to 0. Thus, we can't use its size for intersection
    // testing. Use the FrameView geometry instead.
    // 2) An element wider than the ICB can cause us to resize the FrameView so
    // we can zoom out to fit the entire element width.
    result = ToLayoutView(root)->OverflowClipRect(LayoutPoint());
  } else if (root->IsBox() && root->HasOverflowClip()) {
    result = LayoutRect(ToLayoutBox(root)->PhysicalContentBoxRect());
  } else {
    result = LayoutRect(ToLayoutBoxModelObject(root)->BorderBoundingBox());
  }
  ApplyRootMargin(result, margin);
  return result;
}

void IntersectionGeometry::ApplyRootMargin(LayoutRect& rect,
                                           const Vector<Length>& margin) {
  if (margin.IsEmpty())
    return;

  // TODO(szager): Make sure the spec is clear that left/right margins are
  // resolved against width and not height.
  LayoutUnit top_margin = ComputeMargin(margin[0], rect.Height());
  LayoutUnit right_margin = ComputeMargin(margin[1], rect.Width());
  LayoutUnit bottom_margin = ComputeMargin(margin[2], rect.Height());
  LayoutUnit left_margin = ComputeMargin(margin[3], rect.Width());

  rect.SetX(rect.X() - left_margin);
  rect.SetWidth(rect.Width() + left_margin + right_margin);
  rect.SetY(rect.Y() - top_margin);
  rect.SetHeight(rect.Height() + top_margin + bottom_margin);
}

bool IntersectionGeometry::ClipToRoot(LayoutObject* root,
                                      LayoutObject* target,
                                      const LayoutRect& root_rect,
                                      LayoutRect& intersection_rect) {
  // Map and clip rect into root element coordinates.
  // TODO(szager): the writing mode flipping needs a test.
  LayoutBox* local_ancestor = nullptr;
  if (!RootIsImplicit() || root->GetDocument().IsInMainFrame())
    local_ancestor = ToLayoutBox(root);

  LayoutView* layout_view = target->GetDocument().GetLayoutView();

  unsigned flags = kDefaultVisualRectFlags | kEdgeInclusive;
  if (!layout_view->NeedsPaintPropertyUpdate() &&
      !layout_view->DescendantNeedsPaintPropertyUpdate()) {
    flags |= kUseGeometryMapper;
  }
  bool does_intersect = target->MapToVisualRectInAncestorSpace(
      local_ancestor, intersection_rect, static_cast<VisualRectFlags>(flags));
  if (!does_intersect || !local_ancestor)
    return does_intersect;
  if (local_ancestor->HasOverflowClip())
    intersection_rect.Move(-local_ancestor->ScrolledContentOffset());
  LayoutRect root_clip_rect(root_rect);
  local_ancestor->FlipForWritingMode(root_clip_rect);
  return does_intersect & intersection_rect.InclusiveIntersect(root_clip_rect);
}

unsigned IntersectionGeometry::FirstThresholdGreaterThan(
    float ratio,
    const Vector<float>& thresholds) const {
  unsigned result = 0;
  while (result < thresholds.size() && thresholds[result] <= ratio)
    ++result;
  return result;
}

}  // namespace blink
