// Copyright 2017 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 COMPONENTS_EXO_CLIENT_CONTROLLED_SHELL_SURFACE_H_
#define COMPONENTS_EXO_CLIENT_CONTROLLED_SHELL_SURFACE_H_

#include <memory>
#include <string>

#include "ash/display/screen_orientation_controller.h"
#include "ash/wm/client_controlled_state.h"
#include "base/callback.h"
#include "base/macros.h"
#include "components/exo/shell_surface_base.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/compositor_lock.h"
#include "ui/display/display_observer.h"

namespace ash {
class NonClientFrameViewAsh;
class ImmersiveFullscreenController;
class RoundedCornerDecorator;
class WideFrameView;

namespace mojom {
enum class WindowPinType;
}
}  // namespace ash

namespace exo {
class Surface;

enum class Orientation { PORTRAIT, LANDSCAPE };

// This class implements a ShellSurface whose window state and bounds are
// controlled by a remote shell client rather than the window manager. The
// position specified as part of the geometry is relative to the origin of
// the screen coordinate system.
class ClientControlledShellSurface
    : public ShellSurfaceBase,
      public display::DisplayObserver,
      public ui::CompositorLockClient {
 public:
  ClientControlledShellSurface(Surface* surface,
                               bool can_minimize,
                               int container);
  ~ClientControlledShellSurface() override;

  using GeometryChangedCallback =
      base::RepeatingCallback<void(const gfx::Rect& geometry)>;
  void set_geometry_changed_callback(const GeometryChangedCallback& callback) {
    geometry_changed_callback_ = callback;
  }

  void set_client_controlled_move_resize(bool client_controlled_move_resize) {
    client_controlled_move_resize_ = client_controlled_move_resize;
  }

  // Set bounds in root window coordinates relative to the given display.
  void SetBounds(int64_t display_id, const gfx::Rect& bounds);

  // Called when the client was maximized.
  void SetMaximized();

  // Called when the client was minimized.
  void SetMinimized();

  // Called when the client was restored.
  void SetRestored();

  // Called when the client changed the fullscreen state.
  void SetFullscreen(bool fullscreen);

  // Called when the client was snapped to left.
  void SetSnappedToLeft();

  // Called when the client was snapped to right.
  void SetSnappedToRight();

  // Called when the client was set to PIP.
  void SetPip();

  // Set the callback to run when the surface state changed.
  using StateChangedCallback =
      base::RepeatingCallback<void(ash::mojom::WindowStateType old_state_type,
                                   ash::mojom::WindowStateType new_state_type)>;
  void set_state_changed_callback(
      const StateChangedCallback& state_changed_callback) {
    state_changed_callback_ = state_changed_callback;
  }

  // Set the callback to run when the surface bounds changed.
  using BoundsChangedCallback = base::RepeatingCallback<void(
      ash::mojom::WindowStateType current_state,
      ash::mojom::WindowStateType requested_state,
      int64_t display_id,
      const gfx::Rect& bounds,
      bool is_resize,
      int bounds_change)>;
  void set_bounds_changed_callback(
      const BoundsChangedCallback& bounds_changed_callback) {
    bounds_changed_callback_ = bounds_changed_callback;
  }

  bool has_bounds_changed_callback() const {
    return static_cast<bool>(bounds_changed_callback_);
  }

  // Set the callback to run when the drag operation started.
  using DragStartedCallback = base::RepeatingCallback<void(int direction)>;
  void set_drag_started_callback(const DragStartedCallback& callback) {
    drag_started_callback_ = callback;
  }

  // Set the callback to run when the drag operation finished.
  using DragFinishedCallback = base::RepeatingCallback<void(int, int, bool)>;
  void set_drag_finished_callback(const DragFinishedCallback& callback) {
    drag_finished_callback_ = callback;
  }

  // Pin/unpin the surface. Pinned surface cannot be switched to
  // other windows unless its explicitly unpinned.
  void SetPinned(ash::mojom::WindowPinType type);

  // Sets the surface to be on top of all other windows.
  void SetAlwaysOnTop(bool always_on_top);

  // Controls the visibility of the system UI when this surface is active.
  void SetSystemUiVisibility(bool autohide);

  // Set orientation for surface.
  void SetOrientation(Orientation orientation);

  // Set shadow bounds in surface coordinates. Empty bounds disable the shadow.
  void SetShadowBounds(const gfx::Rect& bounds);

  void SetScale(double scale);

  // Set top inset for surface.
  void SetTopInset(int height);

  // Set resize outset for surface.
  void SetResizeOutset(int outset);

  // Sends the window state change event to client.
  void OnWindowStateChangeEvent(ash::mojom::WindowStateType old_state,
                                ash::mojom::WindowStateType next_state);

  // Sends the window bounds change event to client. |display_id| specifies in
  // which display the surface should live in. |drag_bounds_change| is
  // a masked value of ash::WindowResizer::kBoundsChange_Xxx, and specifies
  // how the bounds was changed. The bounds change event may also come from a
  // snapped window state change |requested_state|.
  void OnBoundsChangeEvent(ash::mojom::WindowStateType current_state,
                           ash::mojom::WindowStateType requested_state,
                           int64_t display_id,
                           const gfx::Rect& bounds,
                           int drag_bounds_change);

  // Sends the window drag events to client.
  void OnDragStarted(int component);
  void OnDragFinished(bool cancel, const gfx::Point& location);

  // Starts the drag operation.
  void StartDrag(int component, const gfx::Point& location);

  // Set if the surface can be maximzied.
  void SetCanMaximize(bool can_maximize);

  // Update the auto hide frame state.
  void UpdateAutoHideFrame();

  // Set the frame button state. The |visible_button_mask| and
  // |enabled_button_mask| is a bit mask whose position is defined
  // in views::CaptionButtonIcon enum.
  void SetFrameButtons(uint32_t frame_visible_button_mask,
                       uint32_t frame_enabled_button_mask);

  // Set the extra title for the surface.
  void SetExtraTitle(const base::string16& extra_title);

  // Set specific orientation lock for this surface. When this surface is in
  // foreground and the display can be rotated (e.g. tablet mode), apply the
  // behavior defined by |orientation_lock|. See more details in
  // //ash/display/screen_orientation_controller.h.
  void SetOrientationLock(ash::OrientationLockType orientation_lock);

  // Overridden from SurfaceDelegate:
  bool IsInputEnabled(Surface* surface) const override;
  void OnSetFrame(SurfaceFrameType type) override;
  void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override;

  // Overridden from views::WidgetDelegate:
  bool CanMaximize() const override;
  views::NonClientFrameView* CreateNonClientFrameView(
      views::Widget* widget) override;
  void SaveWindowPlacement(const gfx::Rect& bounds,
                           ui::WindowShowState show_state) override;
  bool GetSavedWindowPlacement(const views::Widget* widget,
                               gfx::Rect* bounds,
                               ui::WindowShowState* show_state) const override;

  // Overridden from views::View:
  gfx::Size GetMaximumSize() const override;
  void OnDeviceScaleFactorChanged(float old_dsf, float new_dsf) override;

  // Overridden from aura::WindowObserver:
  void OnWindowAddedToRootWindow(aura::Window* window) override;

  // Overridden from display::DisplayObserver:
  void OnDisplayMetricsChanged(const display::Display& display,
                               uint32_t changed_metrics) override;

  // Overridden from ui::CompositorLockClient:
  void CompositorLockTimedOut() override;

  // A factory callback to create ClientControlledState::Delegate.
  using DelegateFactoryCallback = base::RepeatingCallback<
      std::unique_ptr<ash::wm::ClientControlledState::Delegate>(void)>;

  // Set the factory callback for unit test.
  static void SetClientControlledStateDelegateFactoryForTest(
      const DelegateFactoryCallback& callback);

  ash::WideFrameView* wide_frame_for_test() { return wide_frame_.get(); }

 private:
  class ScopedSetBoundsLocally;
  class ScopedLockedToRoot;

  // Overridden from ShellSurfaceBase:
  void SetWidgetBounds(const gfx::Rect& bounds) override;
  gfx::Rect GetShadowBounds() const override;
  void InitializeWindowState(ash::wm::WindowState* window_state) override;
  float GetScale() const override;
  base::Optional<gfx::Rect> GetWidgetBounds() const override;
  gfx::Point GetSurfaceOrigin() const override;
  bool OnPreWidgetCommit() override;
  void OnPostWidgetCommit() override;

  // Update frame status. This may create (or destroy) a wide frame
  // that spans the full work area width if the surface didn't cover
  // the work area.
  void UpdateFrame();

  void UpdateCaptionButtonModel();

  void UpdateBackdrop();

  void UpdateFrameWidth();

  void AttemptToStartDrag(int component, const gfx::Point& location);

  // Lock the compositor if it's not already locked, or extends the
  // lock timeout if it's already locked.
  // TODO(reveman): Remove this when using configure callbacks for orientation.
  // crbug.com/765954
  void EnsureCompositorIsLockedForOrientationChange();

  ash::wm::WindowState* GetWindowState();
  ash::NonClientFrameViewAsh* GetFrameView();
  const ash::NonClientFrameViewAsh* GetFrameView() const;

  GeometryChangedCallback geometry_changed_callback_;

  int top_inset_height_ = 0;
  int pending_top_inset_height_ = 0;

  double scale_ = 1.0;
  double pending_scale_ = 1.0;

  uint32_t frame_visible_button_mask_ = 0;
  uint32_t frame_enabled_button_mask_ = 0;

  StateChangedCallback state_changed_callback_;
  BoundsChangedCallback bounds_changed_callback_;
  DragStartedCallback drag_started_callback_;
  DragFinishedCallback drag_finished_callback_;

  // TODO(reveman): Use configure callbacks for orientation. crbug.com/765954
  Orientation pending_orientation_ = Orientation::LANDSCAPE;
  Orientation orientation_ = Orientation::LANDSCAPE;
  Orientation expected_orientation_ = Orientation::LANDSCAPE;

  ash::wm::ClientControlledState* client_controlled_state_ = nullptr;

  ash::mojom::WindowStateType pending_window_state_ =
      ash::mojom::WindowStateType::NORMAL;

  bool can_maximize_ = true;

  std::unique_ptr<ash::ImmersiveFullscreenController>
      immersive_fullscreen_controller_;

  std::unique_ptr<ash::WideFrameView> wide_frame_;

  std::unique_ptr<ash::RoundedCornerDecorator> decorator_;

  std::unique_ptr<ui::CompositorLock> orientation_compositor_lock_;

  // The orientation to be applied when widget is being created. Only set when
  // widget is not created yet orientation lock is being set.
  ash::OrientationLockType initial_orientation_lock_ =
      ash::OrientationLockType::kAny;

  bool preserve_widget_bounds_ = false;

  DISALLOW_COPY_AND_ASSIGN(ClientControlledShellSurface);
};

}  // namespace exo

#endif  // COMPONENTS_EXO_CLIENT_CONTROLLED_SHELL_SURFACE_H_
