// Copyright (c) 2012 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 "ash/launcher/launcher_view.h"

#include <algorithm>
#include <vector>

#include "ash/launcher/launcher.h"
#include "ash/launcher/launcher_button.h"
#include "ash/launcher/launcher_icon_observer.h"
#include "ash/launcher/launcher_model.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/launcher_view_test_api.h"
#include "ash/test/test_launcher_delegate.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "grit/ui_resources.h"
#include "ui/aura/event.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/window.h"
#include "ui/base/events.h"
#include "ui/compositor/layer.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

namespace ash {
namespace test {

////////////////////////////////////////////////////////////////////////////////
// LauncherIconObserver tests.

class TestLauncherIconObserver : public LauncherIconObserver {
 public:
  TestLauncherIconObserver() : count_(0) {
    Shell::GetInstance()->launcher()->AddIconObserver(this);
  }

  virtual ~TestLauncherIconObserver() {
    Shell::GetInstance()->launcher()->RemoveIconObserver(this);
  }

  // LauncherIconObserver implementation.
  void OnLauncherIconPositionsChanged() OVERRIDE {
    ++count_;
  }

  int count() const { return count_; }
  void Reset() { count_ = 0; }

 private:
  int count_;

  DISALLOW_COPY_AND_ASSIGN(TestLauncherIconObserver);
};

class LauncherViewIconObserverTest : public ash::test::AshTestBase {
 public:
  LauncherViewIconObserverTest() {}
  virtual ~LauncherViewIconObserverTest() {}

  virtual void SetUp() OVERRIDE {
    AshTestBase::SetUp();
    observer_.reset(new TestLauncherIconObserver);
  }

  virtual void TearDown() OVERRIDE {
    observer_.reset();
    AshTestBase::TearDown();
  }

  TestLauncherIconObserver* observer() { return observer_.get(); }

 private:
  scoped_ptr<TestLauncherIconObserver> observer_;

  DISALLOW_COPY_AND_ASSIGN(LauncherViewIconObserverTest);
};

TEST_F(LauncherViewIconObserverTest, AddRemove) {
  ash::test::TestLauncherDelegate* launcher_delegate =
      ash::test::TestLauncherDelegate::instance();
  ASSERT_TRUE(launcher_delegate);

  views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.bounds = gfx::Rect(0, 0, 200, 200);

  scoped_ptr<views::Widget> widget(new views::Widget());
  widget->Init(params);
  launcher_delegate->AddLauncherItem(widget->GetNativeWindow());
  EXPECT_EQ(1, observer()->count());
  observer()->Reset();

  widget->Show();
  widget->GetNativeWindow()->parent()->RemoveChild(widget->GetNativeWindow());
  EXPECT_EQ(1, observer()->count());
  observer()->Reset();
}

TEST_F(LauncherViewIconObserverTest, BoundsChanged) {
  Launcher* launcher = Shell::GetInstance()->launcher();
  gfx::Size launcher_size = launcher->widget()->GetWindowScreenBounds().size();
  int total_width = launcher_size.width() / 2;
  ASSERT_GT(total_width, 0);
  launcher->SetStatusSize(gfx::Size(total_width, launcher_size.height()));
  EXPECT_EQ(1, observer()->count());
  observer()->Reset();
}

////////////////////////////////////////////////////////////////////////////////
// LauncherView tests.

class MockLauncherDelegate : public ash::LauncherDelegate {
 public:
  MockLauncherDelegate() {}
  virtual ~MockLauncherDelegate() {}

  // LauncherDelegate overrides:
  virtual void CreateNewTab() OVERRIDE {}
  virtual void CreateNewWindow() OVERRIDE {}
  virtual void ItemClicked(const ash::LauncherItem& item,
                           int event_flags) OVERRIDE {}
  virtual int GetBrowserShortcutResourceId() OVERRIDE {
    return IDR_AURA_LAUNCHER_BROWSER_SHORTCUT;
  }
  virtual string16 GetTitle(const ash::LauncherItem& item) OVERRIDE {
    return string16();
  }
  virtual ui::MenuModel* CreateContextMenu(
      const ash::LauncherItem& item) OVERRIDE {
    return NULL;
  }
  virtual ui::MenuModel* CreateContextMenuForLauncher() OVERRIDE {
    return NULL;
  }
  virtual ash::LauncherID GetIDByWindow(aura::Window* window) OVERRIDE {
    NOTREACHED();
    return -1;
  }
  virtual bool IsDraggable(const ash::LauncherItem& item) OVERRIDE {
    return true;
  }
};

class LauncherViewTest : public aura::test::AuraTestBase {
 public:
  LauncherViewTest() {}
  virtual ~LauncherViewTest() {}

  virtual void SetUp() OVERRIDE {
    aura::test::AuraTestBase::SetUp();

    model_.reset(new LauncherModel);

    launcher_view_.reset(new internal::LauncherView(model_.get(), &delegate_));
    launcher_view_->Init();
    // The bounds should be big enough for 4 buttons + overflow chevron.
    launcher_view_->SetBounds(0, 0, 500, 50);

    test_api_.reset(new LauncherViewTestAPI(launcher_view_.get()));
    test_api_->SetAnimationDuration(1);  // Speeds up animation for test.
  }

 protected:
  LauncherID AddAppShortcut() {
    LauncherItem item;
    item.type = TYPE_APP_SHORTCUT;
    item.status = STATUS_CLOSED;

    LauncherID id = model_->next_id();
    model_->Add(item);
    test_api_->RunMessageLoopUntilAnimationsDone();
    return id;
  }

  LauncherID AddTabbedBrowserNoWait() {
    LauncherItem item;
    item.type = TYPE_TABBED;
    item.status = STATUS_RUNNING;

    LauncherID id = model_->next_id();
    model_->Add(item);
    return id;
  }

  LauncherID AddTabbedBrowser() {
    LauncherID id = AddTabbedBrowserNoWait();
    test_api_->RunMessageLoopUntilAnimationsDone();
    return id;
  }

  LauncherID AddPlatformAppNoWait() {
    LauncherItem item;
    item.type = TYPE_PLATFORM_APP;
    item.status = STATUS_RUNNING;

    LauncherID id = model_->next_id();
    model_->Add(item);
    return id;
  }

  LauncherID AddPlatformApp() {
    LauncherID id = AddPlatformAppNoWait();
    test_api_->RunMessageLoopUntilAnimationsDone();
    return id;
  }

  void RemoveByID(LauncherID id) {
    model_->RemoveItemAt(model_->ItemIndexByID(id));
    test_api_->RunMessageLoopUntilAnimationsDone();
  }

  internal::LauncherButton* GetButtonByID(LauncherID id) {
    int index = model_->ItemIndexByID(id);
    return test_api_->GetButton(index);
  }

  LauncherItem GetItemByID(LauncherID id) {
    LauncherItems::const_iterator items = model_->ItemByID(id);
    return *items;
  }

  void CheckModelIDs(
      const std::vector<std::pair<LauncherID, views::View*> >& id_map) {
    ASSERT_EQ(static_cast<int>(id_map.size()), test_api_->GetButtonCount());
    ASSERT_EQ(id_map.size(), model_->items().size());
    for (size_t i = 0; i < id_map.size(); ++i) {
      EXPECT_EQ(id_map[i].first, model_->items()[i].id);
      EXPECT_EQ(id_map[i].second, test_api_->GetButton(i));
    }
  }

  views::View* SimulateDrag(int button_index, int destination_index) {
    internal::LauncherButtonHost* button_host = launcher_view_.get();

    // Mouse down.
    views::View* button = test_api_->GetButton(button_index);
    aura::MouseEvent click_event(ui::ET_MOUSE_PRESSED,
                                 button->bounds().origin(),
                                 button->bounds().origin(), 0);
    views::MouseEvent views_click_event(&click_event);
    button_host->MousePressedOnButton(button, views_click_event);

    // Drag.
    views::View* destination = test_api_->GetButton(destination_index);
    aura::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED,
                                destination->bounds().origin(),
                                destination->bounds().origin(), 0);
    views::MouseEvent views_drag_event(&drag_event);
    button_host->MouseDraggedOnButton(button, views_drag_event);
    return button;
  }

  MockLauncherDelegate delegate_;
  scoped_ptr<LauncherModel> model_;
  scoped_ptr<internal::LauncherView> launcher_view_;
  scoped_ptr<LauncherViewTestAPI> test_api_;

 private:
  DISALLOW_COPY_AND_ASSIGN(LauncherViewTest);
};

// Adds browser button until overflow and verifies that the last added browser
// button is hidden.
TEST_F(LauncherViewTest, AddBrowserUntilOverflow) {
  // All buttons should be visible.
  ASSERT_EQ(test_api_->GetLastVisibleIndex() + 1,
            test_api_->GetButtonCount());

  // Add tabbed browser until overflow.
  LauncherID last_added = AddTabbedBrowser();
  while (!test_api_->IsOverflowButtonVisible()) {
    // Added button is visible after animation while in this loop.
    EXPECT_TRUE(GetButtonByID(last_added)->visible());

    last_added = AddTabbedBrowser();
  }

  // The last added button should be invisible.
  EXPECT_FALSE(GetButtonByID(last_added)->visible());
}

// Adds one browser button then adds app shortcut until overflow. Verifies that
// the browser button gets hidden on overflow and last added app shortcut is
// still visible.
TEST_F(LauncherViewTest, AddAppShortcutWithBrowserButtonUntilOverflow) {
  // All buttons should be visible.
  ASSERT_EQ(test_api_->GetLastVisibleIndex() + 1,
            test_api_->GetButtonCount());

  LauncherID browser_button_id = AddTabbedBrowser();

  // Add app shortcut until overflow.
  LauncherID last_added = AddAppShortcut();
  while (!test_api_->IsOverflowButtonVisible()) {
    // Added button is visible after animation while in this loop.
    EXPECT_TRUE(GetButtonByID(last_added)->visible());

    last_added = AddAppShortcut();
  }

  // The last added app short button should be visible.
  EXPECT_TRUE(GetButtonByID(last_added)->visible());
  // And the browser button is invisible.
  EXPECT_FALSE(GetButtonByID(browser_button_id)->visible());
}

// Adds button until overflow then removes first added one. Verifies that
// the last added one changes from invisible to visible and overflow
// chevron is gone.
TEST_F(LauncherViewTest, RemoveButtonRevealsOverflowed) {
  // All buttons should be visible.
  ASSERT_EQ(test_api_->GetLastVisibleIndex() + 1,
            test_api_->GetButtonCount());

  // Add tabbed browser until overflow.
  LauncherID first_added= AddTabbedBrowser();
  LauncherID last_added = first_added;
  while (!test_api_->IsOverflowButtonVisible())
    last_added = AddTabbedBrowser();

  // Expect add more than 1 button. First added is visible and last is not.
  EXPECT_NE(first_added, last_added);
  EXPECT_TRUE(GetButtonByID(first_added)->visible());
  EXPECT_FALSE(GetButtonByID(last_added)->visible());

  // Remove first added.
  RemoveByID(first_added);

  // Last added button becomes visible and overflow chevron is gone.
  EXPECT_TRUE(GetButtonByID(last_added)->visible());
  EXPECT_EQ(1.0f, GetButtonByID(last_added)->layer()->opacity());
  EXPECT_FALSE(test_api_->IsOverflowButtonVisible());
}

// Verifies that remove last overflowed button should hide overflow chevron.
TEST_F(LauncherViewTest, RemoveLastOverflowed) {
  // All buttons should be visible.
  ASSERT_EQ(test_api_->GetLastVisibleIndex() + 1,
            test_api_->GetButtonCount());

  // Add tabbed browser until overflow.
  LauncherID last_added= AddTabbedBrowser();
  while (!test_api_->IsOverflowButtonVisible())
    last_added = AddTabbedBrowser();

  RemoveByID(last_added);
  EXPECT_FALSE(test_api_->IsOverflowButtonVisible());
}

// Adds browser button without waiting for animation to finish and verifies
// that all added buttons are visible.
TEST_F(LauncherViewTest, AddButtonQuickly) {
  // All buttons should be visible.
  ASSERT_EQ(test_api_->GetLastVisibleIndex() + 1,
            test_api_->GetButtonCount());

  // Add a few tabbed browser quickly without wait for animation.
  int added_count = 0;
  while (!test_api_->IsOverflowButtonVisible()) {
    AddTabbedBrowserNoWait();
    ++added_count;
  }

  // LauncherView should be big enough to hold at least 3 new buttons.
  ASSERT_GE(added_count, 3);

  // Wait for the last animation to finish.
  test_api_->RunMessageLoopUntilAnimationsDone();

  // Verifies non-overflow buttons are visible.
  for (int i = 0; i <= test_api_->GetLastVisibleIndex(); ++i) {
    internal::LauncherButton* button = test_api_->GetButton(i);
    EXPECT_TRUE(button->visible()) << "button index=" << i;
    EXPECT_EQ(1.0f, button->layer()->opacity()) << "button index=" << i;
  }
}

// Check that model changes are handled correctly while a launcher icon is being
// dragged.
TEST_F(LauncherViewTest, ModelChangesWhileDragging) {
  internal::LauncherButtonHost* button_host = launcher_view_.get();

  // Initialize |id_map| with the automatically-created launcher buttons.
  std::vector<std::pair<LauncherID, views::View*> > id_map;
  for (size_t i = 0; i < model_->items().size(); ++i) {
    id_map.push_back(std::make_pair(model_->items()[i].id,
                                    test_api_->GetButton(i)));
  }
  ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map));

  // Add 5 app launcher buttons for testing.
  for (int i = 1; i <= 5; ++i) {
    LauncherID id = AddAppShortcut();
    id_map.insert(id_map.begin() + i,
                  std::make_pair(id, test_api_->GetButton(i)));
  }
  ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map));

  // Dragging changes model order.
  views::View* dragged_button = SimulateDrag(1, 3);
  std::rotate(id_map.begin() + 1, id_map.begin() + 2, id_map.begin() + 4);
  ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map));

  // Cancelling the drag operation restores previous order.
  button_host->MouseReleasedOnButton(dragged_button, true);
  std::rotate(id_map.begin() + 1, id_map.begin() + 3, id_map.begin() + 4);
  ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map));

  // Deleting an item keeps the remaining intact.
  dragged_button = SimulateDrag(1, 3);
  model_->RemoveItemAt(3);
  id_map.erase(id_map.begin() + 3);
  ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map));
  button_host->MouseReleasedOnButton(dragged_button, false);

  // Adding a launcher item cancels the drag and respects the order.
  dragged_button = SimulateDrag(1, 3);
  LauncherID new_id = AddAppShortcut();
  id_map.insert(id_map.begin() + 5,
                std::make_pair(new_id, test_api_->GetButton(5)));
  ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map));
  button_host->MouseReleasedOnButton(dragged_button, false);
}

// Confirm that item status changes are reflected in the buttons.
TEST_F(LauncherViewTest, LauncherItemStatus) {
  ASSERT_EQ(test_api_->GetLastVisibleIndex() + 1,
            test_api_->GetButtonCount());

  // Add tabbed browser.
  LauncherID last_added = AddTabbedBrowser();
  LauncherItem item = GetItemByID(last_added);
  int index = model_->ItemIndexByID(last_added);
  internal::LauncherButton* button = GetButtonByID(last_added);
  ASSERT_EQ(internal::LauncherButton::STATE_RUNNING, button->state());
  item.status = ash::STATUS_ACTIVE;
  model_->Set(index, item);
  ASSERT_EQ(internal::LauncherButton::STATE_ACTIVE, button->state());
  item.status = ash::STATUS_ATTENTION;
  model_->Set(index, item);
  ASSERT_EQ(internal::LauncherButton::STATE_ATTENTION, button->state());
  item.status = ash::STATUS_IS_PENDING;
  model_->Set(index, item);
  ASSERT_EQ(internal::LauncherButton::STATE_PENDING, button->state());
}

// Confirm that item status changes are reflected in the buttons
// for platform apps.
TEST_F(LauncherViewTest, LauncherItemStatusPlatformApp) {
  ASSERT_EQ(test_api_->GetLastVisibleIndex() + 1,
            test_api_->GetButtonCount());

  // Add tabbed browser.
  LauncherID last_added = AddPlatformApp();
  LauncherItem item = GetItemByID(last_added);
  int index = model_->ItemIndexByID(last_added);
  internal::LauncherButton* button = GetButtonByID(last_added);
  ASSERT_EQ(internal::LauncherButton::STATE_RUNNING, button->state());
  item.status = ash::STATUS_ACTIVE;
  model_->Set(index, item);
  ASSERT_EQ(internal::LauncherButton::STATE_ACTIVE, button->state());
  item.status = ash::STATUS_ATTENTION;
  model_->Set(index, item);
  ASSERT_EQ(internal::LauncherButton::STATE_ATTENTION, button->state());
  item.status = ash::STATUS_IS_PENDING;
  model_->Set(index, item);
  ASSERT_EQ(internal::LauncherButton::STATE_PENDING, button->state());
}

}  // namespace test
}  // namespace ash
