// Copyright 2013 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 "cc/input/top_controls_manager.h"

#include <stdint.h>

#include <algorithm>

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "cc/input/top_controls_manager_client.h"
#include "cc/output/begin_frame_args.h"
#include "cc/trees/layer_tree_impl.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/transform.h"

namespace cc {
namespace {
// These constants were chosen empirically for their visually pleasant behavior.
// Contact tedchoc@chromium.org for questions about changing these values.
const int64_t kShowHideMaxDurationMs = 200;
}

// static
std::unique_ptr<TopControlsManager> TopControlsManager::Create(
    TopControlsManagerClient* client,
    float top_controls_show_threshold,
    float top_controls_hide_threshold) {
  return base::WrapUnique(new TopControlsManager(
      client, top_controls_show_threshold, top_controls_hide_threshold));
}

TopControlsManager::TopControlsManager(TopControlsManagerClient* client,
                                       float top_controls_show_threshold,
                                       float top_controls_hide_threshold)
    : client_(client),
      animation_start_value_(0.f),
      animation_stop_value_(0.f),
      animation_direction_(NO_ANIMATION),
      permitted_state_(BOTH),
      accumulated_scroll_delta_(0.f),
      baseline_content_offset_(0.f),
      top_controls_show_threshold_(top_controls_hide_threshold),
      top_controls_hide_threshold_(top_controls_show_threshold),
      pinch_gesture_active_(false) {
  CHECK(client_);
}

TopControlsManager::~TopControlsManager() {
}

float TopControlsManager::ControlsTopOffset() const {
  return ContentTopOffset() - TopControlsHeight();
}

float TopControlsManager::ContentTopOffset() const {
  return TopControlsShownRatio() * TopControlsHeight();
}

float TopControlsManager::TopControlsShownRatio() const {
  return client_->CurrentTopControlsShownRatio();
}

float TopControlsManager::TopControlsHeight() const {
  return client_->TopControlsHeight();
}

float TopControlsManager::BottomControlsHeight() const {
  return client_->BottomControlsHeight();
}

float TopControlsManager::ContentBottomOffset() const {
  return TopControlsShownRatio() * BottomControlsHeight();
}

float TopControlsManager::BottomControlsShownRatio() const {
  return TopControlsShownRatio();
}

void TopControlsManager::UpdateTopControlsState(TopControlsState constraints,
                                                TopControlsState current,
                                                bool animate) {
  DCHECK(!(constraints == SHOWN && current == HIDDEN));
  DCHECK(!(constraints == HIDDEN && current == SHOWN));

  permitted_state_ = constraints;

  // Don't do anything if it doesn't matter which state the controls are in.
  if (constraints == BOTH && current == BOTH)
    return;

  // Don't do anything if there is no change in offset.
  float final_shown_ratio = 1.f;
  if (constraints == HIDDEN || current == HIDDEN)
    final_shown_ratio = 0.f;
  if (final_shown_ratio == TopControlsShownRatio())
    return;

  if (animate) {
    SetupAnimation(final_shown_ratio ? SHOWING_CONTROLS : HIDING_CONTROLS);
  } else {
    ResetAnimations();
    client_->SetCurrentTopControlsShownRatio(final_shown_ratio);
  }
}

void TopControlsManager::ScrollBegin() {
  if (pinch_gesture_active_)
    return;

  ResetAnimations();
  ResetBaseline();
}

gfx::Vector2dF TopControlsManager::ScrollBy(
    const gfx::Vector2dF& pending_delta) {
  if (!TopControlsHeight())
    return pending_delta;

  if (pinch_gesture_active_)
    return pending_delta;

  if (permitted_state_ == SHOWN && pending_delta.y() > 0)
    return pending_delta;
  else if (permitted_state_ == HIDDEN && pending_delta.y() < 0)
    return pending_delta;

  accumulated_scroll_delta_ += pending_delta.y();

  float old_offset = ContentTopOffset();
  client_->SetCurrentTopControlsShownRatio(
      (baseline_content_offset_ - accumulated_scroll_delta_) /
      TopControlsHeight());

  // If the controls are fully visible, treat the current position as the
  // new baseline even if the gesture didn't end.
  if (TopControlsShownRatio() == 1.f)
    ResetBaseline();

  ResetAnimations();

  gfx::Vector2dF applied_delta(0.f, old_offset - ContentTopOffset());
  return pending_delta - applied_delta;
}

void TopControlsManager::ScrollEnd() {
  if (pinch_gesture_active_)
    return;

  StartAnimationIfNecessary();
}

void TopControlsManager::PinchBegin() {
  DCHECK(!pinch_gesture_active_);
  pinch_gesture_active_ = true;
  StartAnimationIfNecessary();
}

void TopControlsManager::PinchEnd() {
  DCHECK(pinch_gesture_active_);
  // Pinch{Begin,End} will always occur within the scope of Scroll{Begin,End},
  // so return to a state expected by the remaining scroll sequence.
  pinch_gesture_active_ = false;
  ScrollBegin();
}

void TopControlsManager::MainThreadHasStoppedFlinging() {
  StartAnimationIfNecessary();
}

gfx::Vector2dF TopControlsManager::Animate(base::TimeTicks monotonic_time) {
  if (!has_animation() || !client_->HaveRootScrollLayer())
    return gfx::Vector2dF();

  float old_offset = ContentTopOffset();
  float new_ratio = gfx::Tween::ClampedFloatValueBetween(
      monotonic_time, animation_start_time_, animation_start_value_,
      animation_stop_time_, animation_stop_value_);
  client_->SetCurrentTopControlsShownRatio(new_ratio);

  if (IsAnimationComplete(new_ratio))
    ResetAnimations();

  gfx::Vector2dF scroll_delta(0.f, ContentTopOffset() - old_offset);
  return scroll_delta;
}

void TopControlsManager::ResetAnimations() {
  animation_start_time_ = base::TimeTicks();
  animation_start_value_ = 0.f;
  animation_stop_time_ = base::TimeTicks();
  animation_stop_value_ = 0.f;

  animation_direction_ = NO_ANIMATION;
}

void TopControlsManager::SetupAnimation(AnimationDirection direction) {
  DCHECK_NE(NO_ANIMATION, direction);
  DCHECK(direction != HIDING_CONTROLS || TopControlsShownRatio() > 0.f);
  DCHECK(direction != SHOWING_CONTROLS || TopControlsShownRatio() < 1.f);

  if (has_animation() && animation_direction_ == direction)
    return;

  if (!TopControlsHeight()) {
    client_->SetCurrentTopControlsShownRatio(
        direction == HIDING_CONTROLS ? 0.f : 1.f);
    return;
  }

  animation_start_time_ = base::TimeTicks::Now();
  animation_start_value_ = TopControlsShownRatio();

  const float max_ending_ratio = (direction == SHOWING_CONTROLS ? 1 : -1);
  animation_stop_time_ =
      animation_start_time_ +
      base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs);
  animation_stop_value_ = animation_start_value_ + max_ending_ratio;

  animation_direction_ = direction;
  client_->DidChangeTopControlsPosition();
}

void TopControlsManager::StartAnimationIfNecessary() {
  if (TopControlsShownRatio() == 0.f || TopControlsShownRatio() == 1.f)
    return;

  if (TopControlsShownRatio() >= 1.f - top_controls_hide_threshold_) {
    // If we're showing so much that the hide threshold won't trigger, show.
    SetupAnimation(SHOWING_CONTROLS);
  } else if (TopControlsShownRatio() <= top_controls_show_threshold_) {
    // If we're showing so little that the show threshold won't trigger, hide.
    SetupAnimation(HIDING_CONTROLS);
  } else {
    // If we could be either showing or hiding, we determine which one to
    // do based on whether or not the total scroll delta was moving up or
    // down.
    SetupAnimation(accumulated_scroll_delta_ <= 0.f ? SHOWING_CONTROLS
                                                    : HIDING_CONTROLS);
  }
}

bool TopControlsManager::IsAnimationComplete(float new_ratio) {
  return (animation_direction_ == SHOWING_CONTROLS && new_ratio >= 1.f) ||
         (animation_direction_ == HIDING_CONTROLS && new_ratio <= 0.f);
}

void TopControlsManager::ResetBaseline() {
  accumulated_scroll_delta_ = 0.f;
  baseline_content_offset_ = ContentTopOffset();
}

}  // namespace cc
