// 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 "athena/util/drag_handle.h"

#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/window.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

namespace athena {

class DragHandleDelegateTest : public DragHandleScrollDelegate {
 public:
  explicit DragHandleDelegateTest()
      : begin_delta_(0),
        scroll_end_velocity_(0),
        got_scroll_end_(false),
        update_delta_(0) {}

  ~DragHandleDelegateTest() override {}

  void Reset() {
    begin_delta_ = 0;
    scroll_end_velocity_ = 0;
    got_scroll_end_ = false;
    update_delta_ = 0;
  }

  float begin_delta() { return begin_delta_; }
  float scroll_end_velocity() { return scroll_end_velocity_; }
  bool got_scroll_end() { return got_scroll_end_; }
  float update_delta() { return update_delta_; }

 private:
  // DragHandleScrollDelegate:
  virtual void HandleScrollBegin(float delta) override {
    begin_delta_ = delta;
  }

  virtual void HandleScrollEnd(float velocity) override {
    scroll_end_velocity_ = velocity;
    got_scroll_end_ = true;
  }

  virtual void HandleScrollUpdate(float delta) override {
    update_delta_ = delta;
  }

  float begin_delta_;
  float scroll_end_velocity_;
  bool got_scroll_end_;
  float update_delta_;

  DISALLOW_COPY_AND_ASSIGN(DragHandleDelegateTest);
};

typedef aura::test::AuraTestBase DragHandleTest;

const int kDragHandleWidth = 10;
const int kDragHandleHeight = 100;

ui::GestureEvent CreateGestureEvent(ui::EventType type,
                                    float x,
                                    float delta_x) {
  ui::GestureEvent event(
      x,
      1,
      0,
      base::TimeDelta::FromInternalValue(base::Time::Now().ToInternalValue()),
      type == ui::ET_GESTURE_SCROLL_END
          ? ui::GestureEventDetails(type)
          : ui::GestureEventDetails(type, delta_x, 0));
  event.set_root_location(gfx::PointF(x, 1));
  return event;
}

TEST_F(DragHandleTest, ScrollTest) {
  DragHandleDelegateTest delegate;
  scoped_ptr<views::View> drag_handle(
      CreateDragHandleView(DragHandleScrollDirection::DRAG_HANDLE_HORIZONTAL,
                           &delegate,
                           kDragHandleWidth,
                           kDragHandleHeight));

  views::Widget widget;
  views::Widget::InitParams params(
      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
  params.parent = root_window();
  params.accept_events = true;
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  widget.Init(params);
  widget.SetContentsView(drag_handle.get());
  const gfx::Size& size = gfx::Size(kDragHandleWidth, kDragHandleHeight);
  widget.SetSize(size);
  widget.SetBounds(gfx::Rect(0, 0, size.width(), size.height()));

  const float begin_x = 4.0;
  const float begin_delta = 10.0;
  const float update_delta = 15.0;
  const float fling_velocity = 19.0;

  ui::GestureEvent scroll_begin_model =
      CreateGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, begin_x, begin_delta);
  ui::GestureEvent scroll_update_model =
      CreateGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE,
                         begin_x + update_delta,
                         update_delta - begin_delta);
  ui::GestureEvent scroll_end_model =
      CreateGestureEvent(ui::ET_GESTURE_SCROLL_END, begin_x + update_delta, 0);
  ui::GestureEvent fling_start_model = CreateGestureEvent(
      ui::ET_SCROLL_FLING_START, begin_x + update_delta, fling_velocity);

  // Scroll not ending with a fling.
  ui::GestureEvent e(scroll_begin_model);
  widget.OnGestureEvent(&e);
  EXPECT_EQ(begin_delta, delegate.begin_delta());
  EXPECT_EQ(0, delegate.update_delta());
  EXPECT_FALSE(delegate.got_scroll_end());
  e = ui::GestureEvent(scroll_update_model);
  widget.OnGestureEvent(&e);
  EXPECT_EQ(update_delta, delegate.update_delta());
  EXPECT_FALSE(delegate.got_scroll_end());
  e = ui::GestureEvent(scroll_end_model);
  widget.OnGestureEvent(&e);
  EXPECT_EQ(update_delta, delegate.update_delta());
  EXPECT_TRUE(delegate.got_scroll_end());
  EXPECT_EQ(0, delegate.scroll_end_velocity());

  delegate.Reset();

  // Scroll ending with a fling.
  e = ui::GestureEvent(scroll_begin_model);
  widget.OnGestureEvent(&e);
  e = ui::GestureEvent(scroll_update_model);
  widget.OnGestureEvent(&e);
  e = ui::GestureEvent(fling_start_model);
  widget.OnGestureEvent(&e);
  EXPECT_TRUE(delegate.got_scroll_end());
  EXPECT_EQ(fling_velocity, delegate.scroll_end_velocity());

  delegate.Reset();

  drag_handle.reset();
}

}  // namespace athena
