// Copyright 2014 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 "ui/events/blink/input_scroll_elasticity_controller.h"

#include <math.h>

#include <algorithm>

#include "base/bind.h"
#include "cc/input/input_handler.h"
#include "ui/gfx/geometry/vector2d_conversions.h"

// InputScrollElasticityController is based on
// WebKit/Source/platform/mac/InputScrollElasticityController.mm
/*
 * Copyright (C) 2011 Apple 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

namespace ui {

namespace {

const float kScrollVelocityZeroingTimeout = 0.10f;
const float kRubberbandMinimumRequiredDeltaBeforeStretch = 10;

const float kRubberbandStiffness = 20;
const float kRubberbandAmplitude = 0.31f;
const float kRubberbandPeriod = 1.6f;

// For these functions which compute the stretch amount, always return a
// rounded value, instead of a floating-point value. The reason for this is
// that Blink's scrolling can become erratic with fractional scroll amounts (in
// particular, if you have a scroll offset of 0.5, Blink will never actually
// bring that value back to 0, which breaks the logic used to determine if a
// layer is pinned in a direction).

gfx::Vector2d StretchAmountForTimeDelta(const gfx::Vector2dF& initial_position,
                                        const gfx::Vector2dF& initial_velocity,
                                        float elapsed_time) {
  // Compute the stretch amount at a given time after some initial conditions.
  // Do this by first computing an intermediary position given the initial
  // position, initial velocity, time elapsed, and no external forces. Then
  // take the intermediary position and damp it towards zero by multiplying
  // against a negative exponential.
  float amplitude = kRubberbandAmplitude;
  float period = kRubberbandPeriod;
  float critical_dampening_factor =
      expf((-elapsed_time * kRubberbandStiffness) / period);

  return gfx::ToRoundedVector2d(gfx::ScaleVector2d(
      initial_position +
          gfx::ScaleVector2d(initial_velocity, elapsed_time * amplitude),
      critical_dampening_factor));
}

gfx::Vector2d StretchAmountForReboundDelta(const gfx::Vector2dF& delta) {
  float stiffness = std::max(kRubberbandStiffness, 1.0f);
  return gfx::ToRoundedVector2d(gfx::ScaleVector2d(delta, 1.0f / stiffness));
}

gfx::Vector2d StretchScrollForceForStretchAmount(const gfx::Vector2dF& delta) {
  return gfx::ToRoundedVector2d(
      gfx::ScaleVector2d(delta, kRubberbandStiffness));
}

}  // namespace

InputScrollElasticityController::InputScrollElasticityController(
    cc::ScrollElasticityHelper* helper)
    : helper_(helper),
      state_(kStateInactive),
      momentum_animation_reset_at_next_frame_(false),
      received_overscroll_update_(false),
      weak_factory_(this) {}

InputScrollElasticityController::~InputScrollElasticityController() {
}

base::WeakPtr<InputScrollElasticityController>
InputScrollElasticityController::GetWeakPtr() {
  if (helper_)
    return weak_factory_.GetWeakPtr();
  return base::WeakPtr<InputScrollElasticityController>();
}

void InputScrollElasticityController::ObserveRealScrollBegin(
    bool enter_momentum,
    bool leave_momentum) {
  if (enter_momentum) {
    if (state_ == kStateInactive)
      state_ = kStateMomentumScroll;
  } else if (leave_momentum) {
    scroll_velocity = gfx::Vector2dF();
    last_scroll_event_timestamp_ = base::TimeTicks();
    state_ = kStateActiveScroll;
    pending_overscroll_delta_ = gfx::Vector2dF();
  }
}

void InputScrollElasticityController::ObserveScrollUpdate(
    const gfx::Vector2dF& event_delta,
    const gfx::Vector2dF& unused_scroll_delta,
    const base::TimeTicks event_timestamp,
    const cc::OverscrollBehavior overscroll_behavior,
    bool has_momentum) {
  if (state_ == kStateMomentumAnimated || state_ == kStateInactive)
    return;

  if (!received_overscroll_update_ && !unused_scroll_delta.IsZero()) {
    overscroll_behavior_ = overscroll_behavior;
    received_overscroll_update_ = true;
  }

  UpdateVelocity(event_delta, event_timestamp);
  Overscroll(event_delta, unused_scroll_delta);
  if (has_momentum && !helper_->StretchAmount().IsZero())
    EnterStateMomentumAnimated(event_timestamp);
}

void InputScrollElasticityController::ObserveRealScrollEnd(
    const base::TimeTicks event_timestamp) {
  if (state_ == kStateMomentumAnimated || state_ == kStateInactive)
    return;

  if (helper_->StretchAmount().IsZero()) {
    EnterStateInactive();
  } else {
    EnterStateMomentumAnimated(event_timestamp);
  }
}

void InputScrollElasticityController::ObserveGestureEventAndResult(
    const blink::WebGestureEvent& gesture_event,
    const cc::InputHandlerScrollResult& scroll_result) {
  base::TimeTicks event_timestamp = gesture_event.TimeStamp();

  switch (gesture_event.GetType()) {
    case blink::WebInputEvent::kGestureScrollBegin: {
      received_overscroll_update_ = false;
      overscroll_behavior_ = cc::OverscrollBehavior();
      if (gesture_event.data.scroll_begin.synthetic)
        return;

      bool enter_momentum = gesture_event.data.scroll_begin.inertial_phase ==
                            blink::WebGestureEvent::kMomentumPhase;
      bool leave_momentum = gesture_event.data.scroll_begin.inertial_phase ==
                                blink::WebGestureEvent::kNonMomentumPhase &&
                            gesture_event.data.scroll_begin.delta_hint_units ==
                                blink::WebGestureEvent::kPrecisePixels;
      ObserveRealScrollBegin(enter_momentum, leave_momentum);
      break;
    }
    case blink::WebInputEvent::kGestureScrollUpdate: {
      gfx::Vector2dF event_delta(-gesture_event.data.scroll_update.delta_x,
                                 -gesture_event.data.scroll_update.delta_y);
      bool has_momentum = gesture_event.data.scroll_update.inertial_phase ==
                          blink::WebGestureEvent::kMomentumPhase;
      ObserveScrollUpdate(event_delta, scroll_result.unused_scroll_delta,
                          event_timestamp, scroll_result.overscroll_behavior,
                          has_momentum);
      break;
    }
    case blink::WebInputEvent::kGestureScrollEnd: {
      if (gesture_event.data.scroll_end.synthetic)
        return;
      ObserveRealScrollEnd(event_timestamp);
      break;
    }
    default:
      break;
  }
}

void InputScrollElasticityController::UpdateVelocity(
    const gfx::Vector2dF& event_delta,
    const base::TimeTicks& event_timestamp) {
  float time_delta =
      (event_timestamp - last_scroll_event_timestamp_).InSecondsF();
  if (time_delta < kScrollVelocityZeroingTimeout && time_delta > 0) {
    scroll_velocity = gfx::Vector2dF(event_delta.x() / time_delta,
                                     event_delta.y() / time_delta);
  } else {
    scroll_velocity = gfx::Vector2dF();
  }
  last_scroll_event_timestamp_ = event_timestamp;
}

void InputScrollElasticityController::Overscroll(
    const gfx::Vector2dF& input_delta,
    const gfx::Vector2dF& overscroll_delta) {
  // The effect can be dynamically disabled by setting disallowing user
  // scrolling. When disabled, disallow active or momentum overscrolling, but
  // allow any current overscroll to animate back.
  if (!helper_->IsUserScrollable())
    return;

  gfx::Vector2dF adjusted_overscroll_delta =
      pending_overscroll_delta_ + overscroll_delta;
  pending_overscroll_delta_ = gfx::Vector2dF();

  // Only allow one direction to overscroll at a time, and slightly prefer
  // scrolling vertically by applying the equal case to delta_y.
  if (fabsf(input_delta.y()) >= fabsf(input_delta.x()))
    adjusted_overscroll_delta.set_x(0);
  else
    adjusted_overscroll_delta.set_y(0);

  // Don't allow overscrolling in a direction where scrolling is possible.
  if (!PinnedHorizontally(adjusted_overscroll_delta.x()))
    adjusted_overscroll_delta.set_x(0);
  if (!PinnedVertically(adjusted_overscroll_delta.y()))
    adjusted_overscroll_delta.set_y(0);

  // Don't allow overscrolling in a direction that has
  // OverscrollBehaviorTypeNone.
  if (overscroll_behavior_.x ==
      cc::OverscrollBehavior::kOverscrollBehaviorTypeNone)
    adjusted_overscroll_delta.set_x(0);
  if (overscroll_behavior_.y ==
      cc::OverscrollBehavior::kOverscrollBehaviorTypeNone)
    adjusted_overscroll_delta.set_y(0);

  // Require a minimum of 10 units of overscroll before starting the rubber-band
  // stretch effect, so that small stray motions don't trigger it. If that
  // minimum isn't met, save what remains in |pending_overscroll_delta_| for
  // the next event.
  gfx::Vector2dF old_stretch_amount = helper_->StretchAmount();
  gfx::Vector2dF stretch_scroll_force_delta;
  if (old_stretch_amount.x() != 0 ||
      fabsf(adjusted_overscroll_delta.x()) >=
          kRubberbandMinimumRequiredDeltaBeforeStretch) {
    stretch_scroll_force_delta.set_x(adjusted_overscroll_delta.x());
  } else {
    pending_overscroll_delta_.set_x(adjusted_overscroll_delta.x());
  }
  if (old_stretch_amount.y() != 0 ||
      fabsf(adjusted_overscroll_delta.y()) >=
          kRubberbandMinimumRequiredDeltaBeforeStretch) {
    stretch_scroll_force_delta.set_y(adjusted_overscroll_delta.y());
  } else {
    pending_overscroll_delta_.set_y(adjusted_overscroll_delta.y());
  }

  // Update the stretch amount according to the spring equations.
  if (stretch_scroll_force_delta.IsZero())
    return;
  stretch_scroll_force_ += stretch_scroll_force_delta;
  gfx::Vector2dF new_stretch_amount =
      StretchAmountForReboundDelta(stretch_scroll_force_);
  helper_->SetStretchAmount(new_stretch_amount);
}

void InputScrollElasticityController::EnterStateInactive() {
  DCHECK_NE(kStateInactive, state_);
  DCHECK(helper_->StretchAmount().IsZero());
  state_ = kStateInactive;
  stretch_scroll_force_ = gfx::Vector2dF();
}

void InputScrollElasticityController::EnterStateMomentumAnimated(
    const base::TimeTicks& triggering_event_timestamp) {
  DCHECK_NE(kStateMomentumAnimated, state_);
  state_ = kStateMomentumAnimated;

  momentum_animation_start_time_ = triggering_event_timestamp;
  momentum_animation_initial_stretch_ = helper_->StretchAmount();
  momentum_animation_initial_velocity_ = scroll_velocity;
  momentum_animation_reset_at_next_frame_ = false;

  // Similarly to the logic in Overscroll, prefer vertical scrolling to
  // horizontal scrolling.
  if (fabsf(momentum_animation_initial_velocity_.y()) >=
      fabsf(momentum_animation_initial_velocity_.x()))
    momentum_animation_initial_velocity_.set_x(0);

  if (!CanScrollHorizontally())
    momentum_animation_initial_velocity_.set_x(0);

  if (!CanScrollVertically())
    momentum_animation_initial_velocity_.set_y(0);

  // TODO(crbug.com/394562): This can go away once input is batched to the front
  // of the frame? Then Animate() would always happen after this, so it would
  // have a chance to tick the animation there and would return if any
  // animations were active.
  helper_->RequestOneBeginFrame();
}

void InputScrollElasticityController::Animate(base::TimeTicks time) {
  if (state_ != kStateMomentumAnimated)
    return;

  if (momentum_animation_reset_at_next_frame_) {
    momentum_animation_start_time_ = time;
    momentum_animation_initial_stretch_ = helper_->StretchAmount();
    momentum_animation_initial_velocity_ = gfx::Vector2dF();
    momentum_animation_reset_at_next_frame_ = false;
  }

  float time_delta =
      std::max((time - momentum_animation_start_time_).InSecondsF(), 0.0);

  gfx::Vector2dF old_stretch_amount = helper_->StretchAmount();
  gfx::Vector2dF new_stretch_amount = StretchAmountForTimeDelta(
      momentum_animation_initial_stretch_, momentum_animation_initial_velocity_,
      time_delta);
  gfx::Vector2dF stretch_delta = new_stretch_amount - old_stretch_amount;

  // If the new stretch amount is near zero, set it directly to zero and enter
  // the inactive state.
  if (fabs(new_stretch_amount.x()) < 1 && fabs(new_stretch_amount.y()) < 1) {
    helper_->SetStretchAmount(gfx::Vector2dF());
    EnterStateInactive();
    return;
  }

  // If we are not pinned in the direction of the delta, then the delta is only
  // allowed to decrease the existing stretch -- it cannot increase a stretch
  // until it is pinned.
  if (!PinnedHorizontally(stretch_delta.x())) {
    if (stretch_delta.x() > 0 && old_stretch_amount.x() < 0)
      stretch_delta.set_x(std::min(stretch_delta.x(), -old_stretch_amount.x()));
    else if (stretch_delta.x() < 0 && old_stretch_amount.x() > 0)
      stretch_delta.set_x(std::max(stretch_delta.x(), -old_stretch_amount.x()));
    else
      stretch_delta.set_x(0);
  }
  if (!PinnedVertically(stretch_delta.y())) {
    if (stretch_delta.y() > 0 && old_stretch_amount.y() < 0)
      stretch_delta.set_y(std::min(stretch_delta.y(), -old_stretch_amount.y()));
    else if (stretch_delta.y() < 0 && old_stretch_amount.y() > 0)
      stretch_delta.set_y(std::max(stretch_delta.y(), -old_stretch_amount.y()));
    else
      stretch_delta.set_y(0);
  }
  new_stretch_amount = old_stretch_amount + stretch_delta;

  stretch_scroll_force_ =
      StretchScrollForceForStretchAmount(new_stretch_amount);
  helper_->SetStretchAmount(new_stretch_amount);
  // TODO(danakj): Make this a return value back to the compositor to have it
  // schedule another frame and/or a draw. (Also, crbug.com/551138.)
  helper_->RequestOneBeginFrame();
}

bool InputScrollElasticityController::PinnedHorizontally(
    float direction) const {
  gfx::ScrollOffset scroll_offset = helper_->ScrollOffset();
  gfx::ScrollOffset max_scroll_offset = helper_->MaxScrollOffset();
  if (direction < 0)
    return scroll_offset.x() <= 0;
  if (direction > 0)
    return scroll_offset.x() >= max_scroll_offset.x();
  return false;
}

bool InputScrollElasticityController::PinnedVertically(float direction) const {
  gfx::ScrollOffset scroll_offset = helper_->ScrollOffset();
  gfx::ScrollOffset max_scroll_offset = helper_->MaxScrollOffset();
  if (direction < 0)
    return scroll_offset.y() <= 0;
  if (direction > 0)
    return scroll_offset.y() >= max_scroll_offset.y();
  return false;
}

bool InputScrollElasticityController::CanScrollHorizontally() const {
  return helper_->MaxScrollOffset().x() > 0;
}

bool InputScrollElasticityController::CanScrollVertically() const {
  return helper_->MaxScrollOffset().y() > 0;
}

void InputScrollElasticityController::ReconcileStretchAndScroll() {
  gfx::Vector2dF stretch = helper_->StretchAmount();
  if (stretch.IsZero())
    return;

  gfx::ScrollOffset scroll_offset = helper_->ScrollOffset();
  gfx::ScrollOffset max_scroll_offset = helper_->MaxScrollOffset();

  // Compute stretch_adjustment which will be added to |stretch| and subtracted
  // from the |scroll_offset|.
  gfx::Vector2dF stretch_adjustment;
  if (stretch.x() < 0 && scroll_offset.x() > 0) {
    stretch_adjustment.set_x(
        std::min(-stretch.x(), static_cast<float>(scroll_offset.x())));
  }
  if (stretch.x() > 0 && scroll_offset.x() < max_scroll_offset.x()) {
    stretch_adjustment.set_x(std::max(
        -stretch.x(),
        static_cast<float>(scroll_offset.x() - max_scroll_offset.x())));
  }
  if (stretch.y() < 0 && scroll_offset.y() > 0) {
    stretch_adjustment.set_y(
        std::min(-stretch.y(), static_cast<float>(scroll_offset.y())));
  }
  if (stretch.y() > 0 && scroll_offset.y() < max_scroll_offset.y()) {
    stretch_adjustment.set_y(std::max(
        -stretch.y(),
        static_cast<float>(scroll_offset.y() - max_scroll_offset.y())));
  }

  if (stretch_adjustment.IsZero())
    return;

  gfx::Vector2dF new_stretch_amount = stretch + stretch_adjustment;
  helper_->ScrollBy(-stretch_adjustment);
  helper_->SetStretchAmount(new_stretch_amount);

  // Update the internal state for the active scroll or animation to avoid
  // discontinuities.
  switch (state_) {
    case kStateActiveScroll:
      stretch_scroll_force_ =
          StretchScrollForceForStretchAmount(new_stretch_amount);
      break;
    case kStateMomentumAnimated:
      momentum_animation_reset_at_next_frame_ = true;
      break;
    default:
      // These cases should not be hit because the stretch must be zero in the
      // Inactive and MomentumScroll states.
      NOTREACHED();
      break;
  }
}

}  // namespace ui
