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

#ifndef COMPONENTS_EXO_SHELL_SURFACE_H_
#define COMPONENTS_EXO_SHELL_SURFACE_H_

#include <optional>

#include "ash/focus_cycler.h"
#include "ash/wm/toplevel_window_event_handler.h"
#include "ash/wm/window_state_observer.h"
#include "base/containers/circular_deque.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "components/exo/shell_surface_base.h"
#include "components/exo/shell_surface_observer.h"
#include "ui/base/ui_base_types.h"

namespace ash {
class ScopedAnimationDisabler;
}  // namespace ash

namespace ui {
class CompositorLock;
class Layer;
}  // namespace ui

namespace exo {
class Surface;

// This class implements toplevel surface for which position and state are
// managed by the shell.
class ShellSurface : public ShellSurfaceBase, public ash::WindowStateObserver {
 public:
  // The |origin| is the initial position in screen coordinates. The position
  // specified as part of the geometry is relative to the shell surface.
  ShellSurface(Surface* surface,
               const gfx::Point& origin,
               bool can_minimize,
               int container);
  explicit ShellSurface(Surface* surface);

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

  ~ShellSurface() override;

  // Set the callback to run when the client is asked to configure the surface.
  // The size is a hint, in the sense that the client is free to ignore it if
  // it doesn't resize, pick a smaller size (to satisfy aspect ratio or resize
  // in steps of NxM pixels).
  using ConfigureCallback = base::RepeatingCallback<uint32_t(
      const gfx::Rect& bounds,
      chromeos::WindowStateType state_type,
      bool resizing,
      bool activated,
      const gfx::Vector2d& origin_offset,
      float raster_scale,
      aura::Window::OcclusionState occlusion_state,
      std::optional<chromeos::WindowStateType> restore_state_type)>;
  using OriginChangeCallback =
      base::RepeatingCallback<void(const gfx::Point& origin)>;
  using RotateFocusCallback =
      base::RepeatingCallback<uint32_t(ash::FocusCycler::Direction direction,
                                       bool restart)>;
  using OverviewChangeCallback =
      base::RepeatingCallback<void(bool in_overview)>;

  void set_configure_callback(const ConfigureCallback& configure_callback) {
    configure_callback_ = configure_callback;
  }

  void set_origin_change_callback(
      const OriginChangeCallback& origin_change_callback) {
    origin_change_callback_ = origin_change_callback;
  }

  void set_rotate_focus_callback(const RotateFocusCallback callback) {
    rotate_focus_callback_ = callback;
  }

  void set_overview_change_callback(const OverviewChangeCallback callback) {
    overview_change_callback_ = callback;
  }

  // When the client is asked to configure the surface, it should acknowledge
  // the configure request sometime before the commit. |serial| is the serial
  // from the configure callback.
  void AcknowledgeConfigure(uint32_t serial);

  // Set the "parent" of this surface. This window should be stacked above a
  // parent.
  void SetParent(ShellSurface* parent);

  bool CanMaximize() const override;

  // Maximizes the shell surface.
  void Maximize();

  // Minimize the shell surface.
  void Minimize();

  // Restore the shell surface.
  void Restore();

  // Set fullscreen state for shell surface. When `fullscreen` is true,
  // `display_id` indicates the id of the display where the surface should be
  // shown on, otherwise it gets ignored. When `display::kInvalidDisplayId` is
  // specified the current display will be used.
  void SetFullscreen(bool fullscreen, int64_t display_id);

  // Make the shell surface popup type.
  void SetPopup();

  // Invokes when the surface has reached the end of its own focus rotation.
  // This signals ash to to continue its own focus rotation.
  void AckRotateFocus(uint32_t serial, bool handled);

  // Set event grab on the surface.
  void Grab();

  // Start an interactive resize of surface. |component| is one of the windows
  // HT constants (see ui/base/hit_test.h) and describes in what direction the
  // surface should be resized.
  bool StartResize(int component);

  // Start an interactive move of surface.
  bool StartMove();

  // Sends a wayland request to the surface to rotate focus within itself. If
  // the client was able to rotate, it will return a "handled" response,
  // otherwise it will respond with a "not handled" response.
  // If the client does not support the wayland event, the base class'
  // impl is invoked. In practice, this means that the surface will be focused,
  // but it will not rotate focus within its panes.
  bool RotatePaneFocusFromView(views::View* focused_view,
                               bool forward,
                               bool enable_wrapping) override;

  // Return the initial show state for this surface.
  ui::WindowShowState initial_show_state() { return initial_show_state_; }

  void AddObserver(ShellSurfaceObserver* observer);
  void RemoveObserver(ShellSurfaceObserver* observer);

  void MaybeSetCompositorLockForNextConfigure(int milliseconds);

  // Overridden from SurfaceDelegate:
  void OnSetFrame(SurfaceFrameType type) override;
  void OnSetParent(Surface* parent, const gfx::Point& position) override;

  // Overridden from SurfaceTreeHost:
  void MaybeActivateSurface() override;
  ui::Layer* GetCommitTargetLayer() override;
  const ui::Layer* GetCommitTargetLayer() const override;

  // Overridden from ShellSurfaceBase:
  void InitializeWindowState(ash::WindowState* window_state) override;
  std::optional<gfx::Rect> GetWidgetBounds() const override;
  gfx::Point GetSurfaceOrigin() const override;
  void SetUseImmersiveForFullscreen(bool value) override;
  void OnDidProcessDisplayChanges(
      const DisplayConfigurationChange& configuration_change) override;

  // Overridden from aura::WindowObserver:
  void OnWindowBoundsChanged(aura::Window* window,
                             const gfx::Rect& old_bounds,
                             const gfx::Rect& new_bounds,
                             ui::PropertyChangeReason reason) override;
  void OnWindowAddedToRootWindow(aura::Window* window) override;
  void OnWindowPropertyChanged(aura::Window* window,
                               const void* key,
                               intptr_t old_value) override;

  // Overridden from ash::WindowStateObserver:
  void OnPreWindowStateTypeChange(ash::WindowState* window_state,
                                  chromeos::WindowStateType old_type) override;
  void OnPostWindowStateTypeChange(ash::WindowState* window_state,
                                   chromeos::WindowStateType old_type) override;

  // Overridden from wm::ActivationChangeObserver:
  void OnWindowActivated(ActivationReason reason,
                         aura::Window* gained_active,
                         aura::Window* lost_active) override;

  // Overridden from ShellSurfaceBase:
  gfx::Rect ComputeAdjustedBounds(const gfx::Rect& bounds) const override;
  void SetWidgetBounds(const gfx::Rect& bounds,
                       bool adjusted_by_server) override;
  bool OnPreWidgetCommit() override;
  std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView(
      views::Widget* widget) override;
  void SetRootSurface(Surface* root_surface) override;

  // Overridden from ui::LayerOwner::Observer:
  void OnLayerRecreated(ui::Layer* old_layer) override;

  void EndDrag();

  int resize_component_for_test() const { return resize_component_; }

 private:
  struct Config;

  // Helper class used to coalesce a number of changes into one "configure"
  // callback. Callbacks are suppressed while an instance of this class is
  // instantiated and instead called when the instance is destroyed.
  // If |force_configure_| is true ShellSurface::Configure() will be called
  // even if no changes to shell surface took place during the lifetime of the
  // ScopedConfigure instance.
  class ScopedConfigure {
   public:
    ScopedConfigure(ShellSurface* shell_surface, bool force_configure);

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

    ~ScopedConfigure();

    void set_needs_configure() { needs_configure_ = true; }

   private:
    const raw_ptr<ShellSurface> shell_surface_;
    const bool force_configure_;
    bool needs_configure_ = false;
  };

  class OcclusionObserver : public aura::WindowObserver {
   public:
    explicit OcclusionObserver(ShellSurface* shell_surface,
                               aura::Window* window);
    ~OcclusionObserver() override;

    aura::Window::OcclusionState state() const { return state_; }

    aura::Window::OcclusionState GetInitialStateForConfigure(
        chromeos::WindowStateType state_type);

    // aura::WindowObserver:
    void OnWindowDestroying(aura::Window* window) override;
    void OnWindowOcclusionChanged(aura::Window* window) override;

   private:
    void MaybeConfigure(aura::Window* window);

    // Keeps track of what the current state should be. During initialization,
    // we want to defer sending occlusion messages until everything is ready,
    // so this may be different to the current occlusion state.
    aura::Window::OcclusionState state_;
    const raw_ptr<ShellSurface> shell_surface_;
    base::ScopedObservation<aura::Window, aura::WindowObserver>
        window_observation_{this};
  };

  // Set the parent window of this surface.
  void SetParentWindow(aura::Window* parent);

  // Sets up a transient window manager for this window if it can (i.e. if the
  // surface has a widget with a parent).
  void MaybeMakeTransient();

  // Asks the client to configure its surface. Optionally, the user can override
  // the behaviour to check for window dragging by setting ends_drag to true.
  void Configure(bool ends_drag = false);

  bool GetCanResizeFromSizeConstraints() const override;

  bool AttemptToStartDrag(int component);

  // Utility methods to resolve the initial bounds for the first commit.
  gfx::Rect GetInitialBoundsForState(
      const chromeos::WindowStateType state) const;
  display::Display GetDisplayForInitialBounds() const;

  void UpdateLayerSurfaceRange(ui::Layer* layer,
                               const viz::LocalSurfaceId& current_lsi);

  // Called when the widget window's position in screen coordinates may have
  // changed.
  // TODO(tluk): Screen position changes should be merged into Configure().
  void OnWidgetScreenPositionChanged();

  std::unique_ptr<ash::ScopedAnimationDisabler> animations_disabler_;
  std::optional<OcclusionObserver> occlusion_observer_;

  // Temporarily stores the `host_window()`'s layer when it's recreated for
  // animation. Client-side commits may be directed towards the `old_layer_`
  // instead of `host_window()->layer()` due to the asynchronous config/ack
  // flow.
  base::WeakPtr<ui::Layer> old_layer_;

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

  ConfigureCallback configure_callback_;
  OriginChangeCallback origin_change_callback_;
  RotateFocusCallback rotate_focus_callback_;
  OverviewChangeCallback overview_change_callback_;

  raw_ptr<ScopedConfigure> scoped_configure_ = nullptr;
  base::circular_deque<std::unique_ptr<Config>> pending_configs_;
  // Stores the config which is acked but not yet committed. This will keep the
  // compositor locked until reset after Commit() is called.
  std::unique_ptr<Config> config_waiting_for_commit_;

  // Window resizing is an asynchronous operation. See
  // https://crbug.com/1336706#c22 for a more detailed explanation.
  // |origin_offset_| is typically (0,0). During an asynchronous resizing
  // |origin_offset_| is set to a non-zero value such that it appears as though
  // the ExoShellSurfaceHost has not moved even though ExoShellSurface has
  // already been moved and resized to the new position.
  gfx::Vector2d origin_offset_;
  gfx::Vector2d pending_origin_offset_;
  gfx::Vector2d pending_origin_offset_accumulator_;
  gfx::Rect old_screen_bounds_for_pending_move_;

  int resize_component_ = HTCAPTION;  // HT constant (see ui/base/hit_test.h)
  int pending_resize_component_ = HTCAPTION;
  // TODO(oshima): Use WindowStateType instead.
  ui::WindowShowState initial_show_state_ = ui::SHOW_STATE_DEFAULT;
  bool notify_bounds_changes_ = true;
  bool window_state_is_changing_ = false;
  float pending_raster_scale_ = 1.0;

  struct InflightFocusRotateRequest {
    uint32_t serial;
    ash::FocusCycler::Direction direction;
  };
  std::queue<InflightFocusRotateRequest> rotate_focus_inflight_requests_;

  base::ObserverList<ShellSurfaceObserver> observers_;
};

}  // namespace exo

#endif  // COMPONENTS_EXO_SHELL_SURFACE_H_
