// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_ROOT_WINDOW_CONTROLLER_H_
#define ASH_ROOT_WINDOW_CONTROLLER_H_

#include <map>
#include <memory>
#include <vector>

#include "ash/ash_export.h"
#include "ash/public/cpp/shelf_types.h"
#include "ash/style/ash_color_provider_source.h"
#include "ash/wm/workspace/workspace_types.h"
#include "base/gtest_prod_util.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"

namespace aura {
class Window;
}

namespace gfx {
class Point;
}

namespace ui {
class WindowTreeHost;
class SimpleMenuModel;
}  // namespace ui

namespace views {
class MenuRunner;
class Widget;
}  // namespace views

namespace wm {
class ScopedCaptureClient;
}

namespace ash {
class AccessibilityPanelLayoutManager;
class AlwaysOnTopController;
class AppMenuModelAdapter;
class AshWindowTreeHost;
class LockScreenActionBackgroundController;
enum class LoginStatus;
class RootWindowLayoutManager;
class Shelf;
class ShelfLayoutManager;
class SplitViewController;
class StackingController;
class StatusAreaWidget;
class SystemModalContainerLayoutManager;
class SystemWallpaperController;
class TouchExplorationManager;
class TouchHudDebug;
class TouchHudProjection;
class WallpaperWidgetController;
class WorkAreaInsets;

namespace curtain {
class SecurityCurtainWidgetController;
}

// This class maintains the per root window state for ash. This class
// owns the root window and other dependent objects that should be
// deleted upon the deletion of the root window. This object is
// indirectly owned and deleted by |WindowTreeHostManager|.
// The RootWindowController for particular root window is stored in
// its property (RootWindowSettings) and can be obtained using
// |RootWindowController::ForWindow(aura::Window*)| function.
class ASH_EXPORT RootWindowController {
 public:
  // Enumerates the type of display. If there is only a single display then
  // it is primary. In a multi-display environment one monitor is deemed the
  // PRIMARY and all others SECONDARY.
  enum class RootWindowType { PRIMARY, SECONDARY };

  RootWindowController(const RootWindowController&) = delete;
  RootWindowController& operator=(const RootWindowController&) = delete;

  ~RootWindowController();

  // Creates and Initialize the RootWindowController for primary display.
  // Returns a pointer to the newly created controller.
  static RootWindowController* CreateForPrimaryDisplay(AshWindowTreeHost* host);

  // Creates and Initialize the RootWindowController for secondary displays.
  // Returns a pointer to the newly created controller.
  static RootWindowController* CreateForSecondaryDisplay(
      AshWindowTreeHost* host);

  // Returns a RootWindowController of the window's root window.
  static RootWindowController* ForWindow(const aura::Window* window);

  // Returns the RootWindowController of the target root window.
  static RootWindowController* ForTargetRootWindow();

  static std::vector<RootWindowController*> root_window_controllers() {
    return root_window_controllers_ ? *root_window_controllers_
                                    : std::vector<RootWindowController*>();
  }

  AshWindowTreeHost* ash_host() { return ash_host_.get(); }
  const AshWindowTreeHost* ash_host() const { return ash_host_.get(); }

  aura::WindowTreeHost* GetHost();
  const aura::WindowTreeHost* GetHost() const;
  aura::Window* GetRootWindow();
  const aura::Window* GetRootWindow() const;

  SplitViewController* split_view_controller() const {
    return split_view_controller_.get();
  }

  Shelf* shelf() const { return shelf_.get(); }

  TouchHudDebug* touch_hud_debug() const { return touch_hud_debug_; }
  TouchHudProjection* touch_hud_projection() const {
    return touch_hud_projection_;
  }

  // Set touch HUDs for this root window controller. The root window controller
  // will not own the HUDs; their lifetimes are managed by themselves. Whenever
  // the widget showing a HUD is being destroyed (e.g. because of detaching a
  // display), the HUD deletes itself.
  void set_touch_hud_debug(TouchHudDebug* hud) { touch_hud_debug_ = hud; }
  void set_touch_hud_projection(TouchHudProjection* hud) {
    touch_hud_projection_ = hud;
  }

  RootWindowLayoutManager* root_window_layout_manager() {
    return root_window_layout_manager_;
  }

  // Returns parameters of the work area associated with this root window.
  WorkAreaInsets* work_area_insets() { return work_area_insets_.get(); }

  // Access the shelf layout manager associated with this root
  // window controller, NULL if no such shelf exists.
  ShelfLayoutManager* GetShelfLayoutManager();

  // Returns the layout manager for the appropriate modal-container. If the
  // window is inside the lockscreen modal container, then the layout manager
  // for that is returned. Otherwise the layout manager for the default modal
  // container is returned.
  // If no window is specified (i.e. |window| is null), then the lockscreen
  // modal container is used if the screen is currently locked. Otherwise, the
  // default modal container is used.
  SystemModalContainerLayoutManager* GetSystemModalLayoutManager(
      aura::Window* window);

  AlwaysOnTopController* always_on_top_controller() {
    return always_on_top_controller_.get();
  }

  // May return null, for example for a secondary monitor at the login screen.
  StatusAreaWidget* GetStatusAreaWidget();

  // Returns if system tray and its widget is visible.
  bool IsSystemTrayVisible();

  // True if the window can receive events on this root window.
  bool CanWindowReceiveEvents(aura::Window* window);

  // Returns the window events will be targeted at for the specified location
  // (in screen coordinates).
  //
  // NOTE: the returned window may not contain the location as resize handles
  // may extend outside the bounds of the window.
  aura::Window* FindEventTarget(const gfx::Point& location_in_screen);

  // Gets the last location seen in a mouse event in this root window's
  // coordinates. This may return a point outside the root window's bounds.
  gfx::Point GetLastMouseLocationInRoot();

  aura::Window* GetContainer(int container_id);
  const aura::Window* GetContainer(int container_id) const;

  WallpaperWidgetController* wallpaper_widget_controller() {
    return wallpaper_widget_controller_.get();
  }

  LockScreenActionBackgroundController*
  lock_screen_action_background_controller() {
    return lock_screen_action_background_controller_.get();
  }

  AshColorProviderSource* color_provider_source() {
    return color_provider_source_.get();
  }

  // Deletes associated objects and clears the state, but doesn't delete
  // the root window yet. This is used to delete a secondary displays'
  // root window safely when the display disconnect signal is received,
  // which may come while we're in the nested run loop.
  void Shutdown();

  // Deletes all child windows and performs necessary cleanup.
  void CloseChildWindows();

  // Moves child windows to |dest|.
  // TODO(afakhry): Consider renaming this function to avoid misuse. It is only
  // called by WindowTreeHostManager::DeleteHost(), and has destructive side
  // effects like deleting the workspace controllers, so it shouldn't be called
  // for something else.
  void MoveWindowsTo(aura::Window* dest);

  // Initialize touch HUDs if necessary.
  void InitTouchHuds();

  // Returns the topmost window or one of its transient parents, if any of them
  // are in fullscreen mode.
  // TODO(afakhry): Rename this to imply getting the fullscreen window on the
  // currently active desk on this root.
  aura::Window* GetWindowForFullscreenMode();

  // Returns true if window is fulllscreen and the shelf is hidden.
  bool IsInFullscreenMode();

  // If touch exploration is enabled, update the touch exploration
  // controller so that synthesized touch events are anchored at this point.
  void SetTouchAccessibilityAnchorPoint(const gfx::Point& anchor_point);

  // Shows a context menu at the |location_in_screen|.
  void ShowContextMenu(const gfx::Point& location_in_screen,
                       ui::MenuSourceType source_type);
  void HideContextMenu();
  void HideContextMenuNoAnimation();
  bool IsContextMenuShown() const;

  // Called when the login status changes after login (such as lock/unlock).
  void UpdateAfterLoginStatusChange(LoginStatus status);

  void CreateAmbientWidget();
  void CloseAmbientWidget(bool immediately);
  bool HasAmbientWidget() const;

  views::Widget* ambient_widget_for_testing() { return ambient_widget_.get(); }
  AppMenuModelAdapter* menu_model_adapter_for_testing() {
    return root_window_menu_model_adapter_.get();
  }

  // Returns accessibility panel layout manager for this root window.
  AccessibilityPanelLayoutManager* GetAccessibilityPanelLayoutManagerForTest();

  void SetSecurityCurtainWidgetController(
      std::unique_ptr<curtain::SecurityCurtainWidgetController> controller);
  void ClearSecurityCurtainWidgetController();
  curtain::SecurityCurtainWidgetController*
  security_curtain_widget_controller();

 private:
  FRIEND_TEST_ALL_PREFIXES(RootWindowControllerTest,
                           ContextMenuDisappearsInTabletMode);

  // Takes ownership of |ash_host|.
  explicit RootWindowController(AshWindowTreeHost* ash_host);

  // Initializes the RootWindowController based on |root_window_type|.
  void Init(RootWindowType root_window_type);

  void InitLayoutManagers(
      std::unique_ptr<RootWindowLayoutManager> root_window_layout_manager);

  AccessibilityPanelLayoutManager* GetAccessibilityPanelLayoutManager() const;

  // Creates the containers (aura::Windows) used by the shell.
  void CreateContainers();

  // Creates a new window for use as a container.
  aura::Window* CreateContainer(int window_id,
                                const char* name,
                                aura::Window* parent);

  // Initializes |system_wallpaper_| and possibly also |boot_splash_screen_|.
  // The initial color is determined by the |root_window_type| and whether or
  // not this is the first boot.
  void CreateSystemWallpaper(RootWindowType root_window_type);

  // Callback for MenuRunner.
  void OnMenuClosed();

  // Passed as callback to |wallpaper_widget_controller_| - run when the
  // wallpaper widget is first set.
  void OnFirstWallpaperWidgetSet();

  std::unique_ptr<AshWindowTreeHost> ash_host_;
  // |ash_host_| as a WindowTreeHost.
  aura::WindowTreeHost* window_tree_host_;

  // LayoutManagers are owned by the window they are installed on.
  RootWindowLayoutManager* root_window_layout_manager_ = nullptr;

  std::unique_ptr<WallpaperWidgetController> wallpaper_widget_controller_;

  std::unique_ptr<AlwaysOnTopController> always_on_top_controller_;

  // Manages the context menu.
  std::unique_ptr<AppMenuModelAdapter> root_window_menu_model_adapter_;
  std::unique_ptr<ui::SimpleMenuModel> sort_apps_submenu_;

  std::unique_ptr<StackingController> stacking_controller_;

  std::unique_ptr<SplitViewController> split_view_controller_;

  // The shelf controller for this root window. Exists for the entire lifetime
  // of the RootWindowController so that it is safe for observers to be added
  // to it during construction of the shelf widget and status tray.
  std::unique_ptr<Shelf> shelf_;

  std::unique_ptr<SystemWallpaperController> system_wallpaper_;

  // Responsible for initializing TouchExplorationController when spoken
  // feedback is on.
  std::unique_ptr<TouchExplorationManager> touch_exploration_manager_;

  // Heads-up displays for touch events. These HUDs are not owned by the root
  // window controller and manage their own lifetimes.
  TouchHudDebug* touch_hud_debug_ = nullptr;
  TouchHudProjection* touch_hud_projection_ = nullptr;

  std::unique_ptr<::wm::ScopedCaptureClient> capture_client_;

  std::unique_ptr<LockScreenActionBackgroundController>
      lock_screen_action_background_controller_;

  std::unique_ptr<views::Widget> ambient_widget_;

  std::unique_ptr<curtain::SecurityCurtainWidgetController>
      security_curtain_widget_controller_;

  std::unique_ptr<AshColorProviderSource> color_provider_source_;

  // Whether child windows have been closed during shutdown. Exists to avoid
  // calling related cleanup code more than once.
  bool did_close_child_windows_ = false;

  std::unique_ptr<WorkAreaInsets> work_area_insets_;

  static std::vector<RootWindowController*>* root_window_controllers_;
};

}  // namespace ash

#endif  // ASH_ROOT_WINDOW_CONTROLLER_H_
