/*
 * Copyright (C) 2013 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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/frame/visual_viewport.h"

#include <memory>

#include "cc/layers/picture_layer.h"
#include "cc/layers/scrollbar_layer_interface.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/page_scale_constraints.h"
#include "third_party/blink/renderer/core/frame/page_scale_constraints_set.h"
#include "third_party/blink/renderer/core/frame/root_frame_viewport.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/text_autosizer.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/geometry/double_rect.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h"

namespace blink {

VisualViewport::VisualViewport(Page& owner)
    : page_(&owner),
      scale_(1),
      browser_controls_adjustment_(0),
      max_page_scale_(-1),
      track_pinch_zoom_stats_for_page_(false),
      unique_id_(NewUniqueObjectId()) {
  Reset();
}

TransformPaintPropertyNode* VisualViewport::GetPageScaleNode() const {
  return scale_transform_node_.get();
}

TransformPaintPropertyNode* VisualViewport::GetScrollTranslationNode() const {
  return translation_transform_node_.get();
}

ScrollPaintPropertyNode* VisualViewport::GetScrollNode() const {
  return scroll_node_.get();
}

void VisualViewport::UpdatePaintPropertyNodes(
    scoped_refptr<const TransformPaintPropertyNode> transform_parent,
    scoped_refptr<const ScrollPaintPropertyNode> scroll_parent) {
  DCHECK(transform_parent);
  DCHECK(scroll_parent);

  if (inner_viewport_container_layer_) {
    inner_viewport_container_layer_->SetLayerState(
        PropertyTreeState(&TransformPaintPropertyNode::Root(),
                          &ClipPaintPropertyNode::Root(),
                          &EffectPaintPropertyNode::Root()),
        IntPoint());
  }

  {
    TransformationMatrix scale_transform;
    scale_transform.Scale(Scale());
    TransformPaintPropertyNode::State state{scale_transform, FloatPoint3D()};
    state.compositor_element_id = GetCompositorElementId();

    if (!scale_transform_node_) {
      scale_transform_node_ = TransformPaintPropertyNode::Create(
          *transform_parent, std::move(state));
    } else {
      scale_transform_node_->Update(*transform_parent, std::move(state));
    }
  }

  if (page_scale_layer_) {
    page_scale_layer_->SetLayerState(
        PropertyTreeState(scale_transform_node_.get(),
                          &ClipPaintPropertyNode::Root(),
                          &EffectPaintPropertyNode::Root()),
        IntPoint());
  }

  {
    ScrollPaintPropertyNode::State state;
    state.container_rect = IntRect(IntPoint(), ExcludeScrollbars(size_));
    state.contents_rect = IntRect(IntPoint(), ContentsSize());

    state.user_scrollable_horizontal =
        UserInputScrollable(kHorizontalScrollbar);
    state.user_scrollable_vertical = UserInputScrollable(kVerticalScrollbar);
    state.scrolls_inner_viewport = true;
    state.max_scroll_offset_affected_by_page_scale = true;
    state.compositor_element_id = GetCompositorScrollElementId();

    if (!scroll_node_) {
      scroll_node_ =
          ScrollPaintPropertyNode::Create(*scroll_parent, std::move(state));
    } else {
      scroll_node_->Update(*scroll_parent, std::move(state));
    }
  }

  {
    TransformationMatrix translate_transform;
    ScrollOffset scroll_position = GetScrollOffset();
    translate_transform.Translate(-scroll_position.Width(),
                                  -scroll_position.Height());
    TransformPaintPropertyNode::State state{translate_transform,
                                            FloatPoint3D()};
    state.scroll = scroll_node_;
    if (!translation_transform_node_) {
      translation_transform_node_ = TransformPaintPropertyNode::Create(
          *scale_transform_node_, std::move(state));
    } else {
      translation_transform_node_->Update(*scale_transform_node_,
                                          std::move(state));
    }
  }

  if (inner_viewport_scroll_layer_) {
    inner_viewport_scroll_layer_->SetLayerState(
        PropertyTreeState(translation_transform_node_.get(),
                          &ClipPaintPropertyNode::Root(),
                          &EffectPaintPropertyNode::Root()),
        IntPoint());
  }
}

VisualViewport::~VisualViewport() {
  SendUMAMetrics();
}

void VisualViewport::Trace(blink::Visitor* visitor) {
  visitor->Trace(page_);
  ScrollableArea::Trace(visitor);
}

void VisualViewport::UpdateStyleAndLayoutIgnorePendingStylesheets() const {
  if (!MainFrame())
    return;

  if (Document* document = MainFrame()->GetDocument())
    document->UpdateStyleAndLayoutIgnorePendingStylesheets();
}

void VisualViewport::EnqueueScrollEvent() {
  if (!RuntimeEnabledFeatures::VisualViewportAPIEnabled())
    return;

  if (Document* document = MainFrame()->GetDocument())
    document->EnqueueVisualViewportScrollEvent();
}

void VisualViewport::EnqueueResizeEvent() {
  if (!RuntimeEnabledFeatures::VisualViewportAPIEnabled())
    return;

  if (Document* document = MainFrame()->GetDocument())
    document->EnqueueVisualViewportResizeEvent();
}

void VisualViewport::SetSize(const IntSize& size) {
  if (size_ == size)
    return;

  TRACE_EVENT2("blink", "VisualViewport::setSize", "width", size.Width(),
               "height", size.Height());
  bool width_did_change = size.Width() != size_.Width();
  size_ = size;

  if (inner_viewport_container_layer_) {
    inner_viewport_container_layer_->SetSize(size_);
    inner_viewport_scroll_layer_->CcLayer()->SetScrollable(
        static_cast<gfx::Size>(size_));

    // Need to re-compute sizes for the overlay scrollbars.
    InitializeScrollbars();
  }

  if (!MainFrame())
    return;

  EnqueueResizeEvent();

  bool autosizer_needs_updating =
      width_did_change && MainFrame()->GetSettings() &&
      MainFrame()->GetSettings()->TextAutosizingEnabled();

  if (autosizer_needs_updating) {
    // This needs to happen after setting the m_size member since it'll be read
    // in the update call.
    if (TextAutosizer* text_autosizer =
            MainFrame()->GetDocument()->GetTextAutosizer())
      text_autosizer->UpdatePageInfoInAllFrames();
  }
}

void VisualViewport::Reset() {
  SetScaleAndLocation(1, FloatPoint());
}

void VisualViewport::MainFrameDidChangeSize() {
  TRACE_EVENT0("blink", "VisualViewport::mainFrameDidChangeSize");

  // In unit tests we may not have initialized the layer tree.
  if (inner_viewport_scroll_layer_)
    inner_viewport_scroll_layer_->SetSize(ContentsSize());

  ClampToBoundaries();
}

FloatRect VisualViewport::VisibleRect(
    IncludeScrollbarsInRect scrollbar_inclusion) const {
  FloatSize visible_size(size_);

  if (scrollbar_inclusion == kExcludeScrollbars)
    visible_size = FloatSize(ExcludeScrollbars(size_));

  visible_size.Expand(0, browser_controls_adjustment_);
  visible_size.Scale(1 / scale_);

  return FloatRect(FloatPoint(GetScrollOffset()), visible_size);
}

FloatRect VisualViewport::VisibleRectInDocument(
    IncludeScrollbarsInRect scrollbar_inclusion) const {
  if (!MainFrame() || !MainFrame()->View())
    return FloatRect();

  FloatPoint view_location =
      FloatPoint(MainFrame()->View()->GetScrollableArea()->GetScrollOffset());
  return FloatRect(view_location, VisibleRect(scrollbar_inclusion).Size());
}

FloatPoint VisualViewport::ViewportCSSPixelsToRootFrame(
    const FloatPoint& point) const {
  // Note, this is in CSS Pixels so we don't apply scale.
  FloatPoint point_in_root_frame = point;
  point_in_root_frame.Move(GetScrollOffset());
  return point_in_root_frame;
}

void VisualViewport::SetLocation(const FloatPoint& new_location) {
  SetScaleAndLocation(scale_, new_location);
}

void VisualViewport::Move(const ScrollOffset& delta) {
  SetLocation(FloatPoint(offset_ + delta));
}

void VisualViewport::SetScale(float scale) {
  SetScaleAndLocation(scale, FloatPoint(offset_));
}

double VisualViewport::OffsetLeft() const {
  if (!MainFrame())
    return 0;

  UpdateStyleAndLayoutIgnorePendingStylesheets();

  return VisibleRect().X() / MainFrame()->PageZoomFactor();
}

double VisualViewport::OffsetTop() const {
  if (!MainFrame())
    return 0;

  UpdateStyleAndLayoutIgnorePendingStylesheets();

  return VisibleRect().Y() / MainFrame()->PageZoomFactor();
}

double VisualViewport::Width() const {
  UpdateStyleAndLayoutIgnorePendingStylesheets();
  return VisibleWidthCSSPx();
}

double VisualViewport::Height() const {
  UpdateStyleAndLayoutIgnorePendingStylesheets();
  return VisibleHeightCSSPx();
}

double VisualViewport::ScaleForVisualViewport() const {
  return Scale();
}

void VisualViewport::SetScaleAndLocation(float scale,
                                         const FloatPoint& location) {
  if (DidSetScaleOrLocation(scale, location)) {
    NotifyRootFrameViewport();
    Document* document = MainFrame()->GetDocument();
    if (AXObjectCache* cache = document->ExistingAXObjectCache()) {
      cache->HandleScaleAndLocationChanged(document);
    }
  }
}

double VisualViewport::VisibleWidthCSSPx() const {
  if (!MainFrame())
    return 0;

  float zoom = MainFrame()->PageZoomFactor();
  float width_css_px = VisibleRect().Width() / zoom;
  return width_css_px;
}

double VisualViewport::VisibleHeightCSSPx() const {
  if (!MainFrame())
    return 0;

  float zoom = MainFrame()->PageZoomFactor();
  float height_css_px = VisibleRect().Height() / zoom;
  return height_css_px;
}

bool VisualViewport::DidSetScaleOrLocation(float scale,
                                           const FloatPoint& location) {
  if (!MainFrame())
    return false;

  bool values_changed = false;

  if (!std::isnan(scale) && !std::isinf(scale)) {
    float clamped_scale = GetPage()
                              .GetPageScaleConstraintsSet()
                              .FinalConstraints()
                              .ClampToConstraints(scale);
    if (clamped_scale != scale_) {
      scale_ = clamped_scale;
      values_changed = true;
      GetPage().GetChromeClient().PageScaleFactorChanged();
      EnqueueResizeEvent();
    }
  }

  ScrollOffset clamped_offset = ClampScrollOffset(ToScrollOffset(location));

  // TODO(bokan): If the offset is invalid, we might end up in an infinite
  // recursion as we reenter this function on clamping. It would be cleaner to
  // avoid reentrancy but for now just prevent the stack overflow.
  // crbug.com/702771.
  if (std::isnan(clamped_offset.Width()) ||
      std::isnan(clamped_offset.Height()) ||
      std::isinf(clamped_offset.Width()) || std::isinf(clamped_offset.Height()))
    return false;

  if (clamped_offset != offset_) {
    offset_ = clamped_offset;
    GetScrollAnimator().SetCurrentOffset(offset_);

    // SVG runs with accelerated compositing disabled so no
    // ScrollingCoordinator.
    if (ScrollingCoordinator* coordinator = GetPage().GetScrollingCoordinator())
      coordinator->ScrollableAreaScrollLayerDidChange(this);

    EnqueueScrollEvent();

    MainFrame()->View()->DidChangeScrollOffset();
    values_changed = true;
  }

  if (!values_changed)
    return false;

  MainFrame()->GetEventHandler().DispatchFakeMouseMoveEventSoon(
      MouseEventManager::FakeMouseMoveReason::kDuringScroll);

  probe::didChangeViewport(MainFrame());
  MainFrame()->Loader().SaveScrollState();

  ClampToBoundaries();

  return true;
}

bool VisualViewport::MagnifyScaleAroundAnchor(float magnify_delta,
                                              const FloatPoint& anchor) {
  const float old_page_scale = Scale();
  const float new_page_scale =
      GetPage().GetChromeClient().ClampPageScaleFactorToLimits(magnify_delta *
                                                               old_page_scale);
  if (new_page_scale == old_page_scale)
    return false;
  if (!MainFrame() || !MainFrame()->View())
    return false;

  // Keep the center-of-pinch anchor in a stable position over the course
  // of the magnify.
  // TODO(bokan): Looks like we call into setScaleAndLocation with infinity for
  // the location so it seems either old or newPageScale is invalid.
  // crbug.com/702771.
  FloatPoint anchor_at_old_scale = anchor.ScaledBy(1.f / old_page_scale);
  FloatPoint anchor_at_new_scale = anchor.ScaledBy(1.f / new_page_scale);
  FloatSize anchor_delta = anchor_at_old_scale - anchor_at_new_scale;

  // First try to use the anchor's delta to scroll the LocalFrameView.
  FloatSize anchor_delta_unused_by_scroll = anchor_delta;

  // Manually bubble any remaining anchor delta up to the visual viewport.
  FloatPoint new_location(FloatPoint(GetScrollOffset()) +
                          anchor_delta_unused_by_scroll);
  SetScaleAndLocation(new_page_scale, new_location);
  return true;
}

void VisualViewport::CreateLayerTree() {
  if (inner_viewport_scroll_layer_)
    return;

  DCHECK(!overlay_scrollbar_horizontal_ && !overlay_scrollbar_vertical_ &&
         !overscroll_elasticity_layer_ && !page_scale_layer_ &&
         !inner_viewport_container_layer_);

  // FIXME: The root transform layer should only be created on demand.
  root_transform_layer_ = GraphicsLayer::Create(*this);
  inner_viewport_container_layer_ = GraphicsLayer::Create(*this);
  overscroll_elasticity_layer_ = GraphicsLayer::Create(*this);
  page_scale_layer_ = GraphicsLayer::Create(*this);
  inner_viewport_scroll_layer_ = GraphicsLayer::Create(*this);
  overlay_scrollbar_horizontal_ = GraphicsLayer::Create(*this);
  overlay_scrollbar_vertical_ = GraphicsLayer::Create(*this);

  ScrollingCoordinator* coordinator = GetPage().GetScrollingCoordinator();
  DCHECK(coordinator);
  inner_viewport_scroll_layer_->SetIsContainerForFixedPositionLayers(true);
  coordinator->UpdateUserInputScrollable(this);

  // Set masks to bounds so the compositor doesn't clobber a manually
  // set inner viewport container layer size.
  inner_viewport_container_layer_->SetMasksToBounds(
      GetPage().GetSettings().GetMainFrameClipsContent());
  inner_viewport_container_layer_->SetSize(size_);

  inner_viewport_scroll_layer_->CcLayer()->SetScrollable(
      static_cast<gfx::Size>(size_));
  DCHECK(MainFrame());
  DCHECK(MainFrame()->GetDocument());
  inner_viewport_scroll_layer_->SetElementId(GetCompositorScrollElementId());
  page_scale_layer_->SetElementId(GetCompositorElementId());

  root_transform_layer_->AddChild(inner_viewport_container_layer_.get());
  inner_viewport_container_layer_->AddChild(overscroll_elasticity_layer_.get());
  overscroll_elasticity_layer_->AddChild(page_scale_layer_.get());
  page_scale_layer_->AddChild(inner_viewport_scroll_layer_.get());

  // Ensure this class is set as the scroll layer's ScrollableArea.
  coordinator->ScrollableAreaScrollLayerDidChange(this);

  InitializeScrollbars();
}

void VisualViewport::AttachLayerTree(GraphicsLayer* current_layer_tree_root) {
  TRACE_EVENT1("blink", "VisualViewport::attachLayerTree",
               "currentLayerTreeRoot", (bool)current_layer_tree_root);
  if (!current_layer_tree_root) {
    if (inner_viewport_scroll_layer_)
      inner_viewport_scroll_layer_->RemoveAllChildren();
    return;
  }

  if (current_layer_tree_root->Parent() &&
      current_layer_tree_root->Parent() == inner_viewport_scroll_layer_.get())
    return;

  DCHECK(inner_viewport_scroll_layer_);
  inner_viewport_scroll_layer_->RemoveAllChildren();
  inner_viewport_scroll_layer_->AddChild(current_layer_tree_root);
}

void VisualViewport::InitializeScrollbars() {
  // Do nothing if not attached to layer tree yet - will initialize upon attach.
  if (!inner_viewport_container_layer_)
    return;

  if (VisualViewportSuppliesScrollbars() &&
      !GetPage().GetSettings().GetHideScrollbars()) {
    if (!overlay_scrollbar_horizontal_->Parent()) {
      inner_viewport_container_layer_->AddChild(
          overlay_scrollbar_horizontal_.get());
      if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
        // TODO(pdr): The viewport overlay scrollbars do not have the correct
        // paint properties. See: https://crbug.com/836910
        overlay_scrollbar_horizontal_->SetLayerState(
            PropertyTreeState(PropertyTreeState::Root()), IntPoint());
      }
    }
    if (!overlay_scrollbar_vertical_->Parent()) {
      inner_viewport_container_layer_->AddChild(
          overlay_scrollbar_vertical_.get());
      if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
        // TODO(pdr): The viewport overlay scrollbars do not have the correct
        // paint properties. See: https://crbug.com/836910
        overlay_scrollbar_vertical_->SetLayerState(
            PropertyTreeState(PropertyTreeState::Root()), IntPoint());
      }
    }

    SetupScrollbar(kHorizontalScrollbar);
    SetupScrollbar(kVerticalScrollbar);
  } else {
    overlay_scrollbar_horizontal_->RemoveFromParent();
    overlay_scrollbar_vertical_->RemoveFromParent();
  }

  // Ensure existing LocalFrameView scrollbars are removed if the visual
  // viewport scrollbars are now supplied, or created if the visual viewport no
  // longer supplies scrollbars.
  LocalFrame* frame = MainFrame();
  if (frame && frame->View())
    frame->View()->VisualViewportScrollbarsChanged();
}

void VisualViewport::SetupScrollbar(ScrollbarOrientation orientation) {
  bool is_horizontal = orientation == kHorizontalScrollbar;
  GraphicsLayer* scrollbar_graphics_layer =
      is_horizontal ? overlay_scrollbar_horizontal_.get()
                    : overlay_scrollbar_vertical_.get();
  std::unique_ptr<ScrollingCoordinator::ScrollbarLayerGroup>&
      scrollbar_layer_group = is_horizontal ? scrollbar_layer_group_horizontal_
                                            : scrollbar_layer_group_vertical_;

  ScrollbarThemeOverlay& theme = ScrollbarThemeOverlay::MobileTheme();
  int thumb_thickness = clampTo<int>(
      std::floor(GetPage().GetChromeClient().WindowToViewportScalar(
          theme.ThumbThickness())));
  int scrollbar_thickness = clampTo<int>(
      std::floor(GetPage().GetChromeClient().WindowToViewportScalar(
          theme.ScrollbarThickness(kRegularScrollbar))));
  int scrollbar_margin = clampTo<int>(
      std::floor(GetPage().GetChromeClient().WindowToViewportScalar(
          theme.ScrollbarMargin())));

  if (!scrollbar_layer_group) {
    ScrollingCoordinator* coordinator = GetPage().GetScrollingCoordinator();
    DCHECK(coordinator);

    scrollbar_layer_group = coordinator->CreateSolidColorScrollbarLayer(
        orientation, thumb_thickness, scrollbar_margin, false,
        GetScrollbarElementId(orientation));

    // The compositor will control the scrollbar's visibility. Set to invisible
    // by default so scrollbars don't show up in layout tests.
    scrollbar_layer_group->layer->SetOpacity(0.f);
    scrollbar_graphics_layer->SetContentsToCcLayer(
        scrollbar_layer_group->layer.get(),
        /*prevent_contents_opaque_changes=*/false);
    scrollbar_graphics_layer->SetDrawsContent(false);
    scrollbar_layer_group->scrollbar_layer->SetScrollElementId(
        inner_viewport_scroll_layer_->CcLayer()->element_id());
  }

  int x_position = is_horizontal
                       ? 0
                       : inner_viewport_container_layer_->Size().Width() -
                             scrollbar_thickness;
  int y_position = is_horizontal
                       ? inner_viewport_container_layer_->Size().Height() -
                             scrollbar_thickness
                       : 0;
  int width = is_horizontal ? inner_viewport_container_layer_->Size().Width() -
                                  scrollbar_thickness
                            : scrollbar_thickness;
  int height = is_horizontal
                   ? scrollbar_thickness
                   : inner_viewport_container_layer_->Size().Height() -
                         scrollbar_thickness;

  // Use the GraphicsLayer to position the scrollbars.
  scrollbar_graphics_layer->SetPosition(FloatPoint(x_position, y_position));
  scrollbar_graphics_layer->SetSize(IntSize(width, height));
  scrollbar_graphics_layer->SetContentsRect(IntRect(0, 0, width, height));
}

bool VisualViewport::VisualViewportSuppliesScrollbars() const {
  return GetPage().GetSettings().GetViewportEnabled();
}

CompositorElementId VisualViewport::GetCompositorElementId() const {
  return CompositorElementIdFromUniqueObjectId(
      unique_id_, CompositorElementIdNamespace::kPrimary);
}

CompositorElementId VisualViewport::GetCompositorScrollElementId() const {
  return CompositorElementIdFromUniqueObjectId(
      unique_id_, CompositorElementIdNamespace::kScroll);
}

bool VisualViewport::ScrollAnimatorEnabled() const {
  return GetPage().GetSettings().GetScrollAnimatorEnabled();
}

PlatformChromeClient* VisualViewport::GetChromeClient() const {
  return &GetPage().GetChromeClient();
}

bool VisualViewport::ShouldUseIntegerScrollOffset() const {
  LocalFrame* frame = MainFrame();
  if (frame && frame->GetSettings() &&
      !frame->GetSettings()->GetPreferCompositingToLCDTextEnabled())
    return true;

  return ScrollableArea::ShouldUseIntegerScrollOffset();
}

void VisualViewport::SetScrollOffset(const ScrollOffset& offset,
                                     ScrollType scroll_type,
                                     ScrollBehavior scroll_behavior) {
  // We clamp the offset here, because the ScrollAnimator may otherwise be
  // set to a non-clamped offset by ScrollableArea::setScrollOffset,
  // which may lead to incorrect scrolling behavior in RootFrameViewport down
  // the line.
  // TODO(eseckler): Solve this instead by ensuring that ScrollableArea and
  // ScrollAnimator are kept in sync. This requires that ScrollableArea always
  // stores fractional offsets and that truncation happens elsewhere, see
  // crbug.com/626315.
  ScrollOffset new_scroll_offset = ClampScrollOffset(offset);
  ScrollableArea::SetScrollOffset(new_scroll_offset, scroll_type,
                                  scroll_behavior);
}

int VisualViewport::ScrollSize(ScrollbarOrientation orientation) const {
  IntSize scroll_dimensions =
      MaximumScrollOffsetInt() - MinimumScrollOffsetInt();
  return (orientation == kHorizontalScrollbar) ? scroll_dimensions.Width()
                                               : scroll_dimensions.Height();
}

IntSize VisualViewport::MinimumScrollOffsetInt() const {
  return IntSize();
}

IntSize VisualViewport::MaximumScrollOffsetInt() const {
  return FlooredIntSize(MaximumScrollOffset());
}

ScrollOffset VisualViewport::MaximumScrollOffset() const {
  if (!MainFrame())
    return ScrollOffset();

  // TODO(bokan): We probably shouldn't be storing the bounds in a float.
  // crbug.com/470718.
  FloatSize frame_view_size(ContentsSize());

  if (browser_controls_adjustment_) {
    float min_scale =
        GetPage().GetPageScaleConstraintsSet().FinalConstraints().minimum_scale;
    frame_view_size.Expand(0, browser_controls_adjustment_ / min_scale);
  }

  frame_view_size.Scale(scale_);
  frame_view_size = FloatSize(FlooredIntSize(frame_view_size));

  FloatSize viewport_size(size_);
  viewport_size.Expand(0, ceilf(browser_controls_adjustment_));

  FloatSize max_position = frame_view_size - viewport_size;
  max_position.Scale(1 / scale_);
  return ScrollOffset(max_position);
}

IntPoint VisualViewport::ClampDocumentOffsetAtScale(const IntPoint& offset,
                                                    float scale) {
  if (!MainFrame() || !MainFrame()->View())
    return IntPoint();

  LocalFrameView* view = MainFrame()->View();

  FloatSize scaled_size(ExcludeScrollbars(size_));
  scaled_size.Scale(1 / scale);

  IntSize visual_viewport_max =
      FlooredIntSize(FloatSize(ContentsSize()) - scaled_size);
  IntSize max =
      view->LayoutViewport()->MaximumScrollOffsetInt() + visual_viewport_max;
  IntSize min =
      view->LayoutViewport()
          ->MinimumScrollOffsetInt();  // VisualViewportMin should be (0, 0)

  IntSize clamped = ToIntSize(offset);
  clamped = clamped.ShrunkTo(max);
  clamped = clamped.ExpandedTo(min);
  return IntPoint(clamped);
}

void VisualViewport::SetBrowserControlsAdjustment(float adjustment) {
  if (browser_controls_adjustment_ == adjustment)
    return;

  browser_controls_adjustment_ = adjustment;
  EnqueueResizeEvent();
}

float VisualViewport::BrowserControlsAdjustment() const {
  return browser_controls_adjustment_;
}

IntRect VisualViewport::ScrollableAreaBoundingBox() const {
  // This method should return the bounding box in the top-level
  // LocalFrameView's coordinate space; however, VisualViewport technically
  // isn't a child of any Frames.  Nonetheless, the VisualViewport always
  // occupies the entire main frame so just return that.
  LocalFrame* frame = MainFrame();

  if (!frame || !frame->View())
    return IntRect();

  return frame->View()->FrameRect();
}

bool VisualViewport::UserInputScrollable(ScrollbarOrientation) const {
  // If there is a non-root fullscreen element, prevent the viewport from
  // scrolling.
  Document* main_document = MainFrame() ? MainFrame()->GetDocument() : nullptr;
  if (main_document) {
    Element* fullscreen_element =
        Fullscreen::FullscreenElementFrom(*main_document);
    if (fullscreen_element)
      return false;
  }
  return true;
}

IntSize VisualViewport::ContentsSize() const {
  LocalFrame* frame = MainFrame();
  if (!frame || !frame->View())
    return IntSize();

  return frame->View()->Size();
}

IntRect VisualViewport::VisibleContentRect(
    IncludeScrollbarsInRect scrollbar_inclusion) const {
  return EnclosingIntRect(VisibleRect(scrollbar_inclusion));
}

scoped_refptr<base::SingleThreadTaskRunner> VisualViewport::GetTimerTaskRunner()
    const {
  return MainFrame()->GetTaskRunner(TaskType::kInternalDefault);
}

void VisualViewport::UpdateScrollOffset(const ScrollOffset& position,
                                        ScrollType scroll_type) {
  if (!DidSetScaleOrLocation(scale_, FloatPoint(position)))
    return;
  if (IsExplicitScrollType(scroll_type)) {
    NotifyRootFrameViewport();
    if (scroll_type != kCompositorScroll && LayerForScrolling())
      LayerForScrolling()->CcLayer()->ShowScrollbars();
  }
}

GraphicsLayer* VisualViewport::LayerForContainer() const {
  return inner_viewport_container_layer_.get();
}

GraphicsLayer* VisualViewport::LayerForScrolling() const {
  return inner_viewport_scroll_layer_.get();
}

GraphicsLayer* VisualViewport::LayerForHorizontalScrollbar() const {
  return overlay_scrollbar_horizontal_.get();
}

GraphicsLayer* VisualViewport::LayerForVerticalScrollbar() const {
  return overlay_scrollbar_vertical_.get();
}

IntRect VisualViewport::ComputeInterestRect(const GraphicsLayer*,
                                            const IntRect&) const {
  return IntRect();
}

void VisualViewport::PaintContents(const GraphicsLayer*,
                                   GraphicsContext&,
                                   GraphicsLayerPaintingPhase,
                                   const IntRect&) const {}

RootFrameViewport* VisualViewport::GetRootFrameViewport() const {
  if (!MainFrame() || !MainFrame()->View())
    return nullptr;

  return MainFrame()->View()->GetRootFrameViewport();
}

LocalFrame* VisualViewport::MainFrame() const {
  return GetPage().MainFrame() && GetPage().MainFrame()->IsLocalFrame()
             ? GetPage().DeprecatedLocalMainFrame()
             : nullptr;
}

IntSize VisualViewport::ExcludeScrollbars(const IntSize& size) const {
  IntSize excluded_size = size;
  if (RootFrameViewport* root_frame_viewport = GetRootFrameViewport()) {
    excluded_size.Expand(-root_frame_viewport->VerticalScrollbarWidth(),
                         -root_frame_viewport->HorizontalScrollbarHeight());
  }
  return excluded_size;
}

bool VisualViewport::ScheduleAnimation() {
  GetPage().GetChromeClient().ScheduleAnimation(MainFrame()->View());
  return true;
}

void VisualViewport::ClampToBoundaries() {
  SetLocation(FloatPoint(offset_));
}

FloatRect VisualViewport::ViewportToRootFrame(
    const FloatRect& rect_in_viewport) const {
  FloatRect rect_in_root_frame = rect_in_viewport;
  rect_in_root_frame.Scale(1 / Scale());
  rect_in_root_frame.Move(GetScrollOffset());
  return rect_in_root_frame;
}

IntRect VisualViewport::ViewportToRootFrame(
    const IntRect& rect_in_viewport) const {
  // FIXME: How to snap to pixels?
  return EnclosingIntRect(ViewportToRootFrame(FloatRect(rect_in_viewport)));
}

FloatRect VisualViewport::RootFrameToViewport(
    const FloatRect& rect_in_root_frame) const {
  FloatRect rect_in_viewport = rect_in_root_frame;
  rect_in_viewport.Move(-GetScrollOffset());
  rect_in_viewport.Scale(Scale());
  return rect_in_viewport;
}

IntRect VisualViewport::RootFrameToViewport(
    const IntRect& rect_in_root_frame) const {
  // FIXME: How to snap to pixels?
  return EnclosingIntRect(RootFrameToViewport(FloatRect(rect_in_root_frame)));
}

FloatPoint VisualViewport::ViewportToRootFrame(
    const FloatPoint& point_in_viewport) const {
  FloatPoint point_in_root_frame = point_in_viewport;
  point_in_root_frame.Scale(1 / Scale(), 1 / Scale());
  point_in_root_frame.Move(GetScrollOffset());
  return point_in_root_frame;
}

FloatPoint VisualViewport::RootFrameToViewport(
    const FloatPoint& point_in_root_frame) const {
  FloatPoint point_in_viewport = point_in_root_frame;
  point_in_viewport.Move(-GetScrollOffset());
  point_in_viewport.Scale(Scale(), Scale());
  return point_in_viewport;
}

IntPoint VisualViewport::ViewportToRootFrame(
    const IntPoint& point_in_viewport) const {
  // FIXME: How to snap to pixels?
  return FlooredIntPoint(
      FloatPoint(ViewportToRootFrame(FloatPoint(point_in_viewport))));
}

IntPoint VisualViewport::RootFrameToViewport(
    const IntPoint& point_in_root_frame) const {
  // FIXME: How to snap to pixels?
  return FlooredIntPoint(
      FloatPoint(RootFrameToViewport(FloatPoint(point_in_root_frame))));
}

void VisualViewport::StartTrackingPinchStats() {
  if (!MainFrame())
    return;

  Document* document = MainFrame()->GetDocument();
  if (!document)
    return;

  if (!document->Url().ProtocolIsInHTTPFamily())
    return;

  track_pinch_zoom_stats_for_page_ = !ShouldDisableDesktopWorkarounds();
}

void VisualViewport::UserDidChangeScale() {
  if (!track_pinch_zoom_stats_for_page_)
    return;

  max_page_scale_ = std::max(max_page_scale_, scale_);
}

void VisualViewport::SendUMAMetrics() {
  if (track_pinch_zoom_stats_for_page_) {
    bool did_scale = max_page_scale_ > 0;

    DEFINE_STATIC_LOCAL(EnumerationHistogram, did_scale_histogram,
                        ("Viewport.DidScalePage", 2));
    did_scale_histogram.Count(did_scale ? 1 : 0);

    if (did_scale) {
      int zoom_percentage = floor(max_page_scale_ * 100);

      // See the PageScaleFactor enumeration in histograms.xml for the bucket
      // ranges.
      int bucket = floor(zoom_percentage / 25.f);

      DEFINE_STATIC_LOCAL(EnumerationHistogram, max_scale_histogram,
                          ("Viewport.MaxPageScale", 21));
      max_scale_histogram.Count(bucket);
    }
  }

  max_page_scale_ = -1;
  track_pinch_zoom_stats_for_page_ = false;
}

bool VisualViewport::ShouldDisableDesktopWorkarounds() const {
  if (!MainFrame() || !MainFrame()->View())
    return false;

  if (!MainFrame()->GetSettings()->GetViewportEnabled())
    return false;

  // A document is considered adapted to small screen UAs if one of these holds:
  // 1. The author specified viewport has a constrained width that is equal to
  //    the initial viewport width.
  // 2. The author has disabled viewport zoom.
  const PageScaleConstraints& constraints =
      GetPage().GetPageScaleConstraintsSet().PageDefinedConstraints();

  return MainFrame()->View()->GetLayoutSize().Width() == size_.Width() ||
         (constraints.minimum_scale == constraints.maximum_scale &&
          constraints.minimum_scale != -1);
}

CompositorAnimationHost* VisualViewport::GetCompositorAnimationHost() const {
  DCHECK(GetPage().MainFrame()->IsLocalFrame());
  ScrollingCoordinator* c = GetPage().GetScrollingCoordinator();
  return c ? c->GetCompositorAnimationHost() : nullptr;
}

CompositorAnimationTimeline* VisualViewport::GetCompositorAnimationTimeline()
    const {
  DCHECK(GetPage().MainFrame()->IsLocalFrame());
  ScrollingCoordinator* c = GetPage().GetScrollingCoordinator();
  return c ? c->GetCompositorAnimationTimeline() : nullptr;
}

void VisualViewport::NotifyRootFrameViewport() const {
  if (!GetRootFrameViewport())
    return;

  GetRootFrameViewport()->DidUpdateVisualViewport();
}

ScrollbarTheme& VisualViewport::GetPageScrollbarTheme() const {
  return GetPage().GetScrollbarTheme();
}

void VisualViewport::SetOverlayScrollbarsHidden(bool hidden) {
  ScrollableArea::SetScrollbarsHiddenIfOverlay(hidden);
}

String VisualViewport::DebugName(const GraphicsLayer* graphics_layer) const {
  String name;
  if (graphics_layer == inner_viewport_container_layer_.get()) {
    name = "Inner Viewport Container Layer";
  } else if (graphics_layer == overscroll_elasticity_layer_.get()) {
    name = "Overscroll Elasticity Layer";
  } else if (graphics_layer == page_scale_layer_.get()) {
    name = "Page Scale Layer";
  } else if (graphics_layer == inner_viewport_scroll_layer_.get()) {
    name = "Inner Viewport Scroll Layer";
  } else if (graphics_layer == overlay_scrollbar_horizontal_.get()) {
    name = "Overlay Scrollbar Horizontal Layer";
  } else if (graphics_layer == overlay_scrollbar_vertical_.get()) {
    name = "Overlay Scrollbar Vertical Layer";
  } else if (graphics_layer == root_transform_layer_.get()) {
    name = "Root Transform Layer";
  } else {
    NOTREACHED();
  }

  return name;
}

const ScrollableArea* VisualViewport::GetScrollableAreaForTesting(
    const GraphicsLayer* layer) const {
  if (layer == inner_viewport_scroll_layer_.get())
    return this;
  return nullptr;
}

}  // namespace blink
