// 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 <algorithm>

#include "base/logging.h"
#include "cc/animation/keyframed_animation_curve.h"
#include "cc/animation/timing_function.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/frame_time.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 kShowHideMaxDurationMs = 200;
}

// static
scoped_ptr<TopControlsManager> TopControlsManager::Create(
    TopControlsManagerClient* client,
    float top_controls_show_threshold,
    float top_controls_hide_threshold) {
  return make_scoped_ptr(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_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();
}

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() {
  DCHECK(!pinch_gesture_active_);
  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() {
  DCHECK(!pinch_gesture_active_);
  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 (!top_controls_animation_ || !client_->HaveRootScrollLayer())
    return gfx::Vector2dF();

  base::TimeDelta time = monotonic_time - base::TimeTicks();

  float old_offset = ContentTopOffset();
  client_->SetCurrentTopControlsShownRatio(
      top_controls_animation_->GetValue(time));

  if (IsAnimationCompleteAtTime(monotonic_time))
    ResetAnimations();

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

void TopControlsManager::ResetAnimations() {
  top_controls_animation_ = nullptr;
  animation_direction_ = NO_ANIMATION;
}

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

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

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

  top_controls_animation_ = KeyframedFloatAnimationCurve::Create();
  base::TimeDelta start_time = gfx::FrameTime::Now() - base::TimeTicks();
  top_controls_animation_->AddKeyframe(
      FloatKeyframe::Create(start_time, TopControlsShownRatio(), nullptr));
  float max_ending_ratio = (direction == SHOWING_CONTROLS ? 1 : -1);
  top_controls_animation_->AddKeyframe(FloatKeyframe::Create(
      start_time + base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs),
      TopControlsShownRatio() + max_ending_ratio,
      EaseTimingFunction::Create()));
  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::IsAnimationCompleteAtTime(base::TimeTicks time) {
  if (!top_controls_animation_)
    return true;

  base::TimeDelta animation_time = time - base::TimeTicks();
  float new_ratio = top_controls_animation_->GetValue(animation_time);

  if ((animation_direction_ == SHOWING_CONTROLS && new_ratio >= 1.f) ||
      (animation_direction_ == HIDING_CONTROLS && new_ratio <= 0.f)) {
    return true;
  }
  return false;
}

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

}  // namespace cc
