// 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 "core/intersection_observer/IntersectionObservation.h"

#include "core/dom/ElementRareData.h"
#include "core/frame/LocalFrame.h"
#include "core/intersection_observer/IntersectionObserver.h"
#include "core/layout/IntersectionGeometry.h"

namespace blink {

IntersectionObservation::IntersectionObservation(IntersectionObserver& observer,
                                                 Element& target)
    : observer_(observer),
      target_(&target),
      // Note that the spec says the initial value of m_lastThresholdIndex
      // should be -1, but since m_lastThresholdIndex is unsigned, we use a
      // different sentinel value.
      last_threshold_index_(kMaxThresholdIndex - 1) {
  UpdateShouldReportRootBoundsAfterDomChange();
}

void IntersectionObservation::ComputeIntersectionObservations(
    DOMHighResTimeStamp timestamp) {
  DCHECK(Observer());
  if (!target_)
    return;
  Vector<Length> root_margin(4);
  root_margin[0] = observer_->TopMargin();
  root_margin[1] = observer_->RightMargin();
  root_margin[2] = observer_->BottomMargin();
  root_margin[3] = observer_->LeftMargin();
  IntersectionGeometry geometry(observer_->root(), *Target(), root_margin,
                                should_report_root_bounds_);
  geometry.ComputeGeometry();

  // 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.
  unsigned new_threshold_index;
  float new_visible_ratio;
  if (geometry.DoesIntersect()) {
    if (geometry.TargetRect().IsEmpty()) {
      new_visible_ratio = 1;
    } else {
      float intersection_area =
          geometry.IntersectionRect().Size().Width().ToFloat() *
          geometry.IntersectionRect().Size().Height().ToFloat();
      float target_area = geometry.TargetRect().Size().Width().ToFloat() *
                          geometry.TargetRect().Size().Height().ToFloat();
      new_visible_ratio = intersection_area / target_area;
    }
    new_threshold_index =
        Observer()->FirstThresholdGreaterThan(new_visible_ratio);
  } else {
    new_visible_ratio = 0;
    new_threshold_index = 0;
  }

  // TODO(tkent): We can't use CHECK_LT due to a compile error.
  CHECK(new_threshold_index < kMaxThresholdIndex);

  if (last_threshold_index_ != new_threshold_index) {
    IntRect snapped_root_bounds = geometry.RootIntRect();
    IntRect* root_bounds_pointer =
        should_report_root_bounds_ ? &snapped_root_bounds : nullptr;
    IntersectionObserverEntry* new_entry = new IntersectionObserverEntry(
        timestamp, new_visible_ratio, geometry.TargetIntRect(),
        root_bounds_pointer, geometry.IntersectionIntRect(),
        geometry.DoesIntersect(), Target());
    Observer()->EnqueueIntersectionObserverEntry(*new_entry);
    SetLastThresholdIndex(new_threshold_index);
  }
}

void IntersectionObservation::Disconnect() {
  DCHECK(Observer());
  if (target_)
    Target()->EnsureIntersectionObserverData().RemoveObservation(*Observer());
  observer_.Clear();
}

void IntersectionObservation::UpdateShouldReportRootBoundsAfterDomChange() {
  if (!Observer()->RootIsImplicit()) {
    should_report_root_bounds_ = true;
    return;
  }
  should_report_root_bounds_ = false;
  LocalFrame* target_frame = Target()->GetDocument().GetFrame();
  if (!target_frame)
    return;
  Frame& root_frame = target_frame->Tree().Top();
  if (&root_frame == target_frame) {
    should_report_root_bounds_ = true;
  } else {
    should_report_root_bounds_ =
        target_frame->GetSecurityContext()->GetSecurityOrigin()->CanAccess(
            root_frame.GetSecurityContext()->GetSecurityOrigin());
  }
}

void IntersectionObservation::Trace(blink::Visitor* visitor) {
  visitor->Trace(observer_);
  visitor->Trace(target_);
}

}  // namespace blink
