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

#include "core/dom/ElementRareData.h"
#include "core/dom/IntersectionObserver.h"
#include "core/frame/FrameView.h"
#include "core/layout/LayoutBox.h"
#include "core/layout/LayoutText.h"
#include "core/layout/LayoutView.h"
#include "core/paint/PaintLayer.h"

namespace blink {

IntersectionObservation::IntersectionObservation(IntersectionObserver& observer, Element& target, bool shouldReportRootBounds)
    : m_observer(observer)
    , m_target(target.ensureIntersectionObserverData().createWeakPtr(&target))
    , m_active(true)
    , m_shouldReportRootBounds(shouldReportRootBounds)
    , m_lastThresholdIndex(0)
{
}

Element* IntersectionObservation::target() const
{
    return toElement(m_target.get());
}

void IntersectionObservation::initializeGeometry(IntersectionGeometry& geometry)
{
    ASSERT(m_target);
    LayoutObject* targetLayoutObject = target()->layoutObject();
    if (targetLayoutObject->isBoxModelObject())
        geometry.targetRect = toLayoutBoxModelObject(targetLayoutObject)->visualOverflowRect();
    else
        geometry.targetRect = toLayoutText(targetLayoutObject)->visualOverflowRect();
    if (!geometry.targetRect.size().width())
        geometry.targetRect.setWidth(LayoutUnit(1));
    if (!geometry.targetRect.size().height())
        geometry.targetRect.setHeight(LayoutUnit(1));
    geometry.intersectionRect = geometry.targetRect;
}

void IntersectionObservation::clipToRoot(LayoutRect& rect)
{
    // Map and clip rect into root element coordinates.
    // TODO(szager): the writing mode flipping needs a test.
    ASSERT(m_target);
    LayoutObject* rootLayoutObject = m_observer->rootLayoutObject();
    LayoutObject* targetLayoutObject = target()->layoutObject();
    targetLayoutObject->mapToVisibleRectInAncestorSpace(toLayoutBoxModelObject(rootLayoutObject), rect, nullptr);
    if (rootLayoutObject->hasOverflowClip()) {
        LayoutBox* rootLayoutBox = toLayoutBox(rootLayoutObject);
        LayoutRect clipRect(LayoutPoint(), LayoutSize(rootLayoutBox->layer()->size()));
        m_observer->applyRootMargin(clipRect);
        rootLayoutBox->flipForWritingMode(rect);
        rect.intersect(clipRect);
        rootLayoutBox->flipForWritingMode(rect);
    }
}

void IntersectionObservation::clipToFrameView(IntersectionGeometry& geometry)
{
    Node* rootNode = m_observer->root();
    LayoutObject* rootLayoutObject = m_observer->rootLayoutObject();
    if (rootLayoutObject->isLayoutView()) {
        geometry.rootRect = LayoutRect(toLayoutView(rootLayoutObject)->frameView()->visibleContentRect());
        m_observer->applyRootMargin(geometry.rootRect);
        geometry.intersectionRect.intersect(geometry.rootRect);
    } else {
        if (rootLayoutObject->isBox())
            geometry.rootRect = LayoutRect(toLayoutBox(rootLayoutObject)->absoluteContentBox());
        else
            geometry.rootRect = LayoutRect(rootLayoutObject->absoluteBoundingBoxRect());
        m_observer->applyRootMargin(geometry.rootRect);
    }

    LayoutPoint scrollPosition(rootNode->document().view()->scrollPosition());
    geometry.targetRect.moveBy(-scrollPosition);
    geometry.intersectionRect.moveBy(-scrollPosition);
    geometry.rootRect.moveBy(-scrollPosition);
}

static void mapRectToDocumentCoordinates(LayoutObject& layoutObject, LayoutRect& rect)
{
    rect = LayoutRect(layoutObject.localToAbsoluteQuad(FloatQuad(FloatRect(rect)), UseTransforms | ApplyContainerFlip | TraverseDocumentBoundaries).boundingBox());
}

bool IntersectionObservation::computeGeometry(IntersectionGeometry& geometry)
{
    ASSERT(m_target);
    LayoutObject* rootLayoutObject = m_observer->rootLayoutObject();
    LayoutObject* targetLayoutObject = target()->layoutObject();
    if (!rootLayoutObject->isBoxModelObject())
        return false;
    if (!targetLayoutObject->isBoxModelObject() && !targetLayoutObject->isText())
        return false;

    // Initialize targetRect and intersectionRect to bounds of target, in target's coordinate space.
    initializeGeometry(geometry);

    // TODO(szager): Support intersection observations for zero-area targets.  For now, we just
    // punt on the observation.
    if (!geometry.targetRect.size().width() || !geometry.targetRect.size().height())
        return false;

    // Clip intersectionRect to the root, and map it to root coordinates.
    clipToRoot(geometry.intersectionRect);

    // Map targetRect into document coordinates.
    mapRectToDocumentCoordinates(*targetLayoutObject, geometry.targetRect);

    // Map intersectionRect into document coordinates.
    mapRectToDocumentCoordinates(*rootLayoutObject, geometry.intersectionRect);

    // Clip intersectionRect to FrameView visible area if necessary, and map all geometry to frame coordinates.
    clipToFrameView(geometry);

    if (geometry.intersectionRect.size().isZero())
        geometry.intersectionRect = LayoutRect();
    if (!m_shouldReportRootBounds)
        geometry.rootRect = LayoutRect();

    return true;
}

void IntersectionObservation::computeIntersectionObservations(double timestamp)
{
    // Pre-oilpan, there will be a delay between the time when the target Element gets deleted
    // (because its ref count dropped to zero) and when this IntersectionObservation gets
    // deleted (during the next gc run, because the target Element is the only thing keeping
    // the IntersectionObservation alive).  During that interval, we need to check that m_target
    // hasn't been cleared.
    Element* targetElement = target();
    if (!targetElement || !isActive())
        return;
    LayoutObject* targetLayoutObject = targetElement->layoutObject();
    // TODO(szager): Support SVG
    if (!targetLayoutObject || (!targetLayoutObject->isBox() && !targetLayoutObject->isInline()))
        return;

    IntersectionGeometry geometry;
    if (!computeGeometry(geometry))
        return;

    float intersectionArea = geometry.intersectionRect.size().width().toFloat() * geometry.intersectionRect.size().height().toFloat();
    float targetArea = geometry.targetRect.size().width().toFloat() * geometry.targetRect.size().height().toFloat();
    if (!targetArea)
        return;
    float newVisibleRatio = intersectionArea / targetArea;
    unsigned newThresholdIndex = observer().firstThresholdGreaterThan(newVisibleRatio);
    if (m_lastThresholdIndex != newThresholdIndex) {
        IntersectionObserverEntry* newEntry = new IntersectionObserverEntry(
            timestamp / 1000.0,
            pixelSnappedIntRect(geometry.targetRect),
            pixelSnappedIntRect(geometry.rootRect),
            pixelSnappedIntRect(geometry.intersectionRect),
            targetElement);
        observer().enqueueIntersectionObserverEntry(*newEntry);
    }
    setLastThresholdIndex(newThresholdIndex);
}

void IntersectionObservation::disconnect()
{
    IntersectionObserver* observer = m_observer;
    clearRootAndRemoveFromTarget();
    observer->removeObservation(*this);
}

void IntersectionObservation::clearRootAndRemoveFromTarget()
{
    if (m_target)
        target()->ensureIntersectionObserverData().removeObservation(observer());
    m_observer.clear();
}

DEFINE_TRACE(IntersectionObservation)
{
    visitor->trace(m_observer);
    visitor->trace(m_target);
}

} // namespace blink
