/*
 * 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.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VISUAL_VIEWPORT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VISUAL_VIEWPORT_H_

#include <memory>

#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h"

namespace cc {
class AnimationHost;
class ScrollbarLayerBase;
}

namespace blink {
enum class PaintPropertyChangeType : unsigned char;
class EffectPaintPropertyNode;
class GraphicsContext;
class IntRect;
class IntSize;
class LocalFrame;
class Page;
class PaintArtifactCompositor;
class RootFrameViewport;
class ScrollPaintPropertyNode;
class TracedValue;
class TransformPaintPropertyNode;
struct PaintPropertyTreeBuilderFragmentContext;

// Represents the visual viewport the user is currently seeing the page through.
// This class corresponds to the InnerViewport on the compositor. It is a
// ScrollableArea; it's offset is set through the GraphicsLayer <-> CC sync
// mechanisms. Its contents is the page's main LocalFrameView, which corresponds
// to the outer viewport. The inner viewport is always contained in the outer
// viewport and can pan within it.
//
// When attached, we will create the following layers:
// - scroll_layer_ (transform: scroll_translation_node_)
// - scrollbar_layer_horizontal_ (optional, transform: DET_or_parent)
// - scrollbar_layer_vertical_ (optional, transform: DET_or_parent)
// (DET_or_parent: device_emulation_transform_node_ if exists,
//  or the parent transform state)
//
// After PrePaint, the property trees will look like this:
//
// Transform tree:
//  parent transform state
//  +- device_emulation_transform_node_ (optional)
//     +- overscroll_elasticity_transform_node_
//        +- page_scale_node__
//           +- scroll_translation_node_ (scroll: scroll_node_)
// Effect tree:
//  parent effect state
//  +- horizontal_scrollbar_effect_node_
//  +- vertical_scrollbar_effect_node_
//
class CORE_EXPORT VisualViewport : public GarbageCollected<VisualViewport>,
                                   public ScrollableArea {
 public:
  explicit VisualViewport(Page&);
  ~VisualViewport() override;

  void Trace(Visitor*) const override;

  void InitializeScrollbars();

  // Sets the location of the visual viewport relative to the outer viewport.
  // The coordinates are in partial CSS pixels.
  void SetLocation(const FloatPoint&);
  // FIXME: This should be called moveBy
  void Move(const ScrollOffset&);

  // The size of the Blink viewport area. See size_ for precise
  // definition.
  void SetSize(const IntSize&);
  IntSize Size() const { return size_; }

  // The area of the layout viewport rect visible in the visual viewport,
  // relative to the layout viewport's top-left corner. i.e. As the page scale
  // is increased, this rect shrinks. Does not account for browser-zoom (ctrl
  // +/- zooming).
  FloatRect VisibleRect(IncludeScrollbarsInRect = kExcludeScrollbars) const;

  // Resets the viewport to initial state.
  void Reset();

  // Let the viewport know that the main frame changed size (either through
  // screen rotation on Android or window resize elsewhere).
  void MainFrameDidChangeSize();

  // Sets scale and location in one operation, preventing intermediate clamping.
  void SetScaleAndLocation(float scale,
                           bool is_pinch_gesture_active,
                           const FloatPoint& location);

  void SetScale(float);
  float Scale() const { return scale_; }
  bool IsPinchGestureActive() const { return is_pinch_gesture_active_; }

  // Convert the given rect in the main LocalFrameView's coordinates into a rect
  // in the viewport. The given and returned rects are in CSS pixels, meaning
  // scale isn't applied.
  FloatPoint ViewportCSSPixelsToRootFrame(const FloatPoint&) const;

  // Clamp the given point, in document coordinates, to the maximum/minimum
  // scroll extents of the viewport within the document.
  IntPoint ClampDocumentOffsetAtScale(const IntPoint& offset, float scale);

  // FIXME: This is kind of a hack. Ideally, we would just resize the
  // viewports to account for browser controls. However, LocalFrameView includes
  // much more than just scrolling so we can't simply resize it without
  // incurring all sorts of side-effects. Until we can seperate out the
  // scrollability aspect from LocalFrameView, we use this method to let
  // VisualViewport make the necessary adjustments so that we don't incorrectly
  // clamp scroll offsets coming from the compositor. crbug.com/422328
  void SetBrowserControlsAdjustment(float);
  float BrowserControlsAdjustment() const;

  // Adjust the viewport's offset so that it remains bounded by the outer
  // viepwort.
  void ClampToBoundaries();

  FloatRect ViewportToRootFrame(const FloatRect&) const;
  IntRect ViewportToRootFrame(const IntRect&) const;
  FloatRect RootFrameToViewport(const FloatRect&) const;
  IntRect RootFrameToViewport(const IntRect&) const;

  FloatPoint ViewportToRootFrame(const FloatPoint&) const;
  FloatPoint RootFrameToViewport(const FloatPoint&) const;
  IntPoint ViewportToRootFrame(const IntPoint&) const;
  IntPoint RootFrameToViewport(const IntPoint&) const;

  // ScrollableArea implementation
  ChromeClient* GetChromeClient() const override;
  SmoothScrollSequencer* GetSmoothScrollSequencer() const override;
  void SetScrollOffset(const ScrollOffset&,
                       mojom::blink::ScrollType,
                       mojom::blink::ScrollBehavior,
                       ScrollCallback on_finish) override;
  void SetScrollOffset(const ScrollOffset&,
                       mojom::blink::ScrollType,
                       mojom::blink::ScrollBehavior =
                           mojom::blink::ScrollBehavior::kInstant) override;
  PhysicalRect ScrollIntoView(
      const PhysicalRect&,
      const mojom::blink::ScrollIntoViewParamsPtr&) override;
  bool IsThrottled() const override {
    // VisualViewport is always in the main frame, so the frame does not get
    // throttled.
    return false;
  }
  bool IsActive() const override { return false; }
  int ScrollSize(ScrollbarOrientation) const override;
  bool IsScrollCornerVisible() const override { return false; }
  IntRect ScrollCornerRect() const override { return IntRect(); }
  IntSize ScrollOffsetInt() const override { return FlooredIntSize(offset_); }
  ScrollOffset GetScrollOffset() const override { return offset_; }
  IntSize MinimumScrollOffsetInt() const override;
  IntSize MaximumScrollOffsetInt() const override;
  ScrollOffset MaximumScrollOffset() const override;
  // Note: Because scrollbars are conceptually owned by the LayoutView,
  // ContentsSize includes the main frame's scrollbars. This is necessary for
  // correct cc Layer sizing.
  IntSize ContentsSize() const override;
  bool ScrollbarsCanBeActive() const override { return false; }
  bool UserInputScrollable(ScrollbarOrientation) const override;
  bool ShouldPlaceVerticalScrollbarOnLeft() const override { return false; }
  CompositorElementId GetScrollElementId() const override;
  bool ScrollAnimatorEnabled() const override;
  void ScrollControlWasSetNeedsPaintInvalidation() override {}
  void UpdateScrollOffset(const ScrollOffset&,
                          mojom::blink::ScrollType) override;
  cc::Layer* LayerForScrolling() const override;
  cc::Layer* LayerForHorizontalScrollbar() const override;
  cc::Layer* LayerForVerticalScrollbar() const override;
  bool ScheduleAnimation() override;
  cc::AnimationHost* GetCompositorAnimationHost() const override;
  CompositorAnimationTimeline* GetCompositorAnimationTimeline() const override;
  IntRect VisibleContentRect(
      IncludeScrollbarsInRect = kExcludeScrollbars) const override;
  scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner()
      const override;
  mojom::blink::ColorScheme UsedColorScheme() const override;

  // VisualViewport scrolling may involve pinch zoom and gets routed through
  // WebViewImpl explicitly rather than via ScrollingCoordinator::DidScroll
  // since it needs to be set in tandem with the page scale delta.
  void DidScroll(const FloatPoint&) final { NOTREACHED(); }

  // Visual Viewport API implementation.
  double OffsetLeft() const;
  double OffsetTop() const;
  double Width() const;
  double Height() const;
  double ScaleForVisualViewport() const;

  // Used to calculate Width and Height above but do not update layout.
  double VisibleWidthCSSPx() const;
  double VisibleHeightCSSPx() const;

  // Used for gathering data on user pinch-zoom statistics.
  void UserDidChangeScale();
  void SendUMAMetrics();
  void StartTrackingPinchStats();

  // Heuristic-based function for determining if we should disable workarounds
  // for viewing websites that are not optimized for mobile devices.
  bool ShouldDisableDesktopWorkarounds() const;

  ScrollbarTheme& GetPageScrollbarTheme() const override;
  bool VisualViewportSuppliesScrollbars() const override;

  const Document* GetDocument() const override;

  TransformPaintPropertyNode* GetDeviceEmulationTransformNode() const;
  TransformPaintPropertyNode* GetOverscrollElasticityTransformNode() const;
  TransformPaintPropertyNode* GetPageScaleNode() const;
  TransformPaintPropertyNode* GetScrollTranslationNode() const;
  ScrollPaintPropertyNode* GetScrollNode() const;

  // Create/update the page scale translation, viewport scroll, and viewport
  // translation property nodes. Returns the maximum paint property change
  // type for any of the viewport's nodes.
  PaintPropertyChangeType UpdatePaintPropertyNodesIfNeeded(
      PaintPropertyTreeBuilderFragmentContext& context);

  void SetNeedsPaintPropertyUpdate() { needs_paint_property_update_ = true; }
  bool NeedsPaintPropertyUpdate() const { return needs_paint_property_update_; }

  void DisposeImpl() override;

  void Paint(GraphicsContext&) const;

 private:
  bool DidSetScaleOrLocation(float scale,
                             bool is_pinch_gesture_active,
                             const FloatPoint& location);

  void CreateLayers();
  void UpdateStyleAndLayout(DocumentUpdateReason) const;

  void EnqueueScrollEvent();
  void EnqueueResizeEvent();

  int ScrollbarThickness() const;
  void UpdateScrollbarLayer(ScrollbarOrientation);

  void NotifyRootFrameViewport() const;

  RootFrameViewport* GetRootFrameViewport() const;

  LocalFrame* LocalMainFrame() const;

  Page& GetPage() const {
    DCHECK(page_);
    return *page_;
  }

  PaintArtifactCompositor* GetPaintArtifactCompositor() const;

  std::unique_ptr<TracedValue> ViewportToTracedValue() const;

  // Contracts the given size by the thickness of any visible scrollbars. Does
  // not contract the size if the scrollbar is overlay.
  IntSize ExcludeScrollbars(const IntSize&) const;

  Member<Page> page_;

  scoped_refptr<cc::Layer> scroll_layer_;
  scoped_refptr<cc::ScrollbarLayerBase> scrollbar_layer_horizontal_;
  scoped_refptr<cc::ScrollbarLayerBase> scrollbar_layer_vertical_;

  PropertyTreeStateOrAlias parent_property_tree_state_;
  scoped_refptr<TransformPaintPropertyNode> device_emulation_transform_node_;
  scoped_refptr<TransformPaintPropertyNode>
      overscroll_elasticity_transform_node_;
  scoped_refptr<TransformPaintPropertyNode> page_scale_node_;
  scoped_refptr<TransformPaintPropertyNode> scroll_translation_node_;
  scoped_refptr<ScrollPaintPropertyNode> scroll_node_;
  scoped_refptr<EffectPaintPropertyNode> horizontal_scrollbar_effect_node_;
  scoped_refptr<EffectPaintPropertyNode> vertical_scrollbar_effect_node_;

  // Offset of the visual viewport from the main frame's origin, in CSS pixels.
  ScrollOffset offset_;
  float scale_;
  bool is_pinch_gesture_active_;

  // The Blink viewport size. This is effectively the size of the rect Blink is
  // rendering into and includes space consumed by scrollbars. While it will
  // not include the URL bar height, Blink is only informed of changes to the
  // URL bar once they're fully committed (all the way hidden or shown). While
  // they're animating or being dragged, size_ will not reflect the changed
  // visible content area. The transient URL bar-caused change to the visible
  // content area is tracked in browser_controls_adjustment.
  IntSize size_;

  // Blink is only resized as a result of showing/hiding the URL bar once
  // they're fully committed (all the way hidden or shown). While they're
  // animating or being dragged, browser_controls_adjustment_ tracks the amount
  // they expand or shrink the visible content height.
  float browser_controls_adjustment_;

  // The maximum page scale the user has zoomed to on the current page. Used
  // only to report statistics about pinch-zoom usage.
  float max_page_scale_;
  bool track_pinch_zoom_stats_for_page_;

  // For page scale animation on page_scale_node_.
  CompositorElementId page_scale_element_id_;
  // For scrolling, on scroll_layer_, scroll_node_, and scroll element ids of
  // scrollbar layers.
  CompositorElementId scroll_element_id_;

  bool needs_paint_property_update_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VISUAL_VIEWPORT_H_
