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

#ifndef CHROME_BROWSER_UI_PANELS_BASE_PANEL_BROWSER_TEST_H_
#define CHROME_BROWSER_UI_PANELS_BASE_PANEL_BROWSER_TEST_H_

#include "base/memory/ref_counted.h"
#include "base/values.h"
#include "chrome/browser/ui/panels/display_settings_provider.h"
#include "chrome/browser/ui/panels/panel.h"
#include "chrome/browser/ui/panels/panel_manager.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest.h"
#include "ui/gfx/rect.h"

class NativePanelTesting;
class StackedPanelCollection;

class BasePanelBrowserTest : public InProcessBrowserTest {
 public:
  class MockDisplaySettingsProvider : public DisplaySettingsProvider {
   public:
    MockDisplaySettingsProvider() { }
    virtual ~MockDisplaySettingsProvider() { }

    virtual void SetPrimaryDisplay(
        const gfx::Rect& display_area, const gfx::Rect& work_area) = 0;
    virtual void SetSecondaryDisplay(
        const gfx::Rect& display_area, const gfx::Rect& work_area) = 0;
    virtual void EnableAutoHidingDesktopBar(DesktopBarAlignment alignment,
                                            bool enabled,
                                            int thickness) = 0;
    virtual void SetDesktopBarVisibility(DesktopBarAlignment alignment,
                                         DesktopBarVisibility visibility) = 0;
    virtual void SetDesktopBarThickness(DesktopBarAlignment alignment,
                                        int thickness) = 0;
    virtual void EnableFullScreenMode(bool enabled) = 0;
  };

  BasePanelBrowserTest();
  virtual ~BasePanelBrowserTest();

  // Linux bots use icewm which activate windows in ways that break
  // certain panel tests. Skip those tests when running on the bots.
  // We do not disable the tests to make it easy for developers to run
  // them locally. [Icewm always activates a window when shown.]
  bool SkipTestIfIceWM();

  // Gnome running compiz refuses to activate a window that was initially
  // created as inactive, causing certain panel tests to fail. These tests
  // pass fine on the bots, but fail for developers as Gnome running compiz
  // is the typical linux dev machine configuration. We do not disable the
  // tests to ensure we still have coverage on the bots.
  bool SkipTestIfCompizWM();

  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE;
  virtual void SetUpOnMainThread() OVERRIDE;

 protected:
  enum ActiveState { SHOW_AS_ACTIVE, SHOW_AS_INACTIVE };

  struct CreatePanelParams {
    std::string name;
    gfx::Rect bounds;
    ActiveState show_flag;
    GURL url;
    bool wait_for_fully_created;
    ActiveState expected_active_state;
    PanelManager::CreateMode create_mode;
    Profile* profile;

    CreatePanelParams(const std::string& name,
                      const gfx::Rect& bounds,
                      ActiveState show_flag);
  };

  Panel* CreatePanelWithParams(const CreatePanelParams& params);
  Panel* CreatePanelWithBounds(const std::string& panel_name,
                               const gfx::Rect& bounds);
  Panel* CreatePanel(const std::string& panel_name);

  Panel* CreateDockedPanel(const std::string& name, const gfx::Rect& bounds);
  Panel* CreateDetachedPanel(const std::string& name, const gfx::Rect& bounds);
  Panel* CreateStackedPanel(const std::string& name,
                            const gfx::Rect& bounds,
                            StackedPanelCollection* stack);

  Panel* CreateInactivePanel(const std::string& name);
  Panel* CreateInactiveDockedPanel(const std::string& name,
                                   const gfx::Rect& bounds);
  Panel* CreateInactiveDetachedPanel(const std::string& name,
                                     const gfx::Rect& bounds);

  void ActivatePanel(Panel* panel);
  void DeactivatePanel(Panel* panel);

  static NativePanelTesting* CreateNativePanelTesting(Panel* panel);

  void WaitForPanelActiveState(Panel* panel, ActiveState state);
  void WaitForWindowSizeAvailable(Panel* panel);
  void WaitForBoundsAnimationFinished(Panel* panel);

  scoped_refptr<extensions::Extension> CreateExtension(
      const base::FilePath::StringType& path,
      extensions::Manifest::Location location,
      const DictionaryValue& extra_value);

  void MoveMouseAndWaitForExpansionStateChange(Panel* panel,
                                               const gfx::Point& position);
  static void MoveMouse(const gfx::Point& position);
  void CloseWindowAndWait(Panel* panel);
  static std::string MakePanelName(int index);

  // Checks if the WM supports activation. This may not be true sometimes on
  // buildbots for example when the wm has crashed.
  static bool WmSupportWindowActivation();

  MockDisplaySettingsProvider* mock_display_settings_provider() const {
    return mock_display_settings_provider_;
  }

  // Some tests might not want to use the mock version.
  void disable_display_settings_mock() {
    mock_display_settings_enabled_ = false;
  }

  static const base::FilePath::CharType* kTestDir;

 private:
  // Passed to and owned by PanelManager.
  MockDisplaySettingsProvider* mock_display_settings_provider_;

  bool mock_display_settings_enabled_;
};

#endif  // CHROME_BROWSER_UI_PANELS_BASE_PANEL_BROWSER_TEST_H_
