// Copyright 2014 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 UI_VIEWS_BRIDGE_MAC_BRIDGED_NATIVE_WIDGET_IMPL_H_
#define UI_VIEWS_BRIDGE_MAC_BRIDGED_NATIVE_WIDGET_IMPL_H_

#import <Cocoa/Cocoa.h>

#include <memory>
#include <vector>

#import "base/mac/scoped_nsobject.h"
#include "base/macros.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "ui/accelerated_widget_mac/ca_transaction_observer.h"
#include "ui/accelerated_widget_mac/display_ca_layer_tree.h"
#include "ui/base/cocoa/command_dispatcher.h"
#include "ui/base/cocoa/ns_view_ids.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/display/display_observer.h"
#include "ui/views/views_export.h"
#import "ui/views_bridge_mac/cocoa_mouse_capture_delegate.h"
#include "ui/views_bridge_mac/mojo/bridged_native_widget.mojom.h"
#include "ui/views_bridge_mac/mojo/text_input_host.mojom.h"

@class BridgedContentView;
@class ModalShowAnimationWithLayer;
@class NativeWidgetMacNSWindow;
@class ViewsNSWindowDelegate;

namespace views_bridge_mac {

namespace mojom {
class BridgedNativeWidgetHost;
class TextInputHost;
}  // namespace mojom

class BridgedNativeWidgetHostHelper;
class CocoaMouseCapture;
class DragDropClient;

}  // namespace views_bridge_mac

namespace views {
namespace test {
class BridgedNativeWidgetTestApi;
}

class CocoaWindowMoveLoop;

using views_bridge_mac::mojom::BridgedNativeWidgetHost;
using views_bridge_mac::BridgedNativeWidgetHostHelper;
using views_bridge_mac::CocoaMouseCapture;
using views_bridge_mac::CocoaMouseCaptureDelegate;

// A bridge to an NSWindow managed by an instance of NativeWidgetMac or
// DesktopNativeWidgetMac. Serves as a helper class to bridge requests from the
// NativeWidgetMac to the Cocoa window. Behaves a bit like an aura::Window.
class VIEWS_EXPORT BridgedNativeWidgetImpl
    : public views_bridge_mac::mojom::BridgedNativeWidget,
      public display::DisplayObserver,
      public ui::CATransactionCoordinator::PreCommitObserver,
      public CocoaMouseCaptureDelegate {
 public:
  // Return the size that |window| will take for the given client area |size|,
  // based on its current style mask.
  static gfx::Size GetWindowSizeForClientSize(NSWindow* window,
                                              const gfx::Size& size);

  // Retrieve a BridgedNativeWidgetImpl* from its id or window.
  static BridgedNativeWidgetImpl* GetFromId(uint64_t bridged_native_widget_id);
  static BridgedNativeWidgetImpl* GetFromNativeWindow(gfx::NativeWindow window);

  // Create an NSWindow for the specified parameters.
  static base::scoped_nsobject<NativeWidgetMacNSWindow> CreateNSWindow(
      const views_bridge_mac::mojom::CreateWindowParams* params);

  // Creates one side of the bridge. |host| and |parent| must not be NULL.
  BridgedNativeWidgetImpl(
      uint64_t bridged_native_widget_id,
      BridgedNativeWidgetHost* host,
      BridgedNativeWidgetHostHelper* host_helper,
      views_bridge_mac::mojom::TextInputHost* text_input_host);
  ~BridgedNativeWidgetImpl() override;

  // Bind |bridge_mojo_binding_| to |request|, and set the connection error
  // callback for |bridge_mojo_binding_| to |connection_closed_callback| (which
  // will delete |this| when the connection is closed).
  void BindRequest(
      views_bridge_mac::mojom::BridgedNativeWidgetAssociatedRequest request,
      base::OnceClosure connection_closed_callback);

  // Initialize the NSWindow by taking ownership of the specified object.
  // TODO(ccameron): When a BridgedNativeWidgetImpl is allocated across a
  // process boundary, it will not be possible to explicitly set an NSWindow in
  // this way.
  void SetWindow(base::scoped_nsobject<NativeWidgetMacNSWindow> window);

  // Set the command dispatcher delegate for the window. This will retain
  // |delegate| for the lifetime of |this|.
  void SetCommandDispatcher(
      NSObject<CommandDispatcherDelegate>* delegate,
      id<UserInterfaceItemCommandHandler> command_handler);

  // Start moving the window, pinned to the mouse cursor, and monitor events.
  // Return true on mouse up or false on premature termination via EndMoveLoop()
  // or when window is destroyed during the drag.
  bool RunMoveLoop(const gfx::Vector2d& drag_offset);
  void EndMoveLoop();

  // Sets the cursor associated with the NSWindow. Retains |cursor|.
  void SetCursor(NSCursor* cursor);

  // Called internally by the NSWindowDelegate when the window is closing.
  void OnWindowWillClose();

  // Called by the NSWindowDelegate when a fullscreen operation begins. If
  // |target_fullscreen_state| is true, the target state is fullscreen.
  // Otherwise, a transition has begun to come out of fullscreen.
  void OnFullscreenTransitionStart(bool target_fullscreen_state);

  // Called when a fullscreen transition completes. If target_fullscreen_state()
  // does not match |actual_fullscreen_state|, a new transition will begin.
  void OnFullscreenTransitionComplete(bool actual_fullscreen_state);

  // Transition the window into or out of fullscreen. This will immediately
  // invert the value of target_fullscreen_state().
  void ToggleDesiredFullscreenState(bool async = false);

  // Called by the NSWindowDelegate when the size of the window changes.
  void OnSizeChanged();

  // Called once by the NSWindowDelegate when the position of the window has
  // changed.
  void OnPositionChanged();

  // Called by the NSWindowDelegate when the visibility of the window may have
  // changed. For example, due to a (de)miniaturize operation, or the window
  // being reordered in (or out of) the screen list.
  void OnVisibilityChanged();

  // Called by the NSWindowDelegate when the system control tint changes.
  void OnSystemControlTintChanged();

  // Called by the NSWindowDelegate on a scale factor or color space change.
  void OnBackingPropertiesChanged();

  // Called by the NSWindowDelegate when the window becomes or resigns key.
  void OnWindowKeyStatusChangedTo(bool is_key);

  // Called by the window show animation when it completes and wants to destroy
  // itself.
  void OnShowAnimationComplete();
  // Sort child NSViews according to their ranking in |rank|.
  void SortSubviews(std::map<NSView*, int> rank);

  BridgedContentView* ns_view() { return bridged_view_; }
  BridgedNativeWidgetHost* host() { return host_; }
  BridgedNativeWidgetHostHelper* host_helper() { return host_helper_; }
  views_bridge_mac::mojom::TextInputHost* text_input_host() const {
    return text_input_host_;
  }
  NSWindow* ns_window();

  views_bridge_mac::DragDropClient* drag_drop_client();
  bool is_translucent_window() const { return is_translucent_window_; }

  // The parent widget specified in Widget::InitParams::parent. If non-null, the
  // parent will close children before the parent closes, and children will be
  // raised above their parent when window z-order changes.
  BridgedNativeWidgetImpl* parent() { return parent_; }
  const std::vector<BridgedNativeWidgetImpl*>& child_windows() {
    return child_windows_;
  }

  bool target_fullscreen_state() const { return target_fullscreen_state_; }
  bool window_visible() const { return window_visible_; }
  bool wants_to_be_visible() const { return wants_to_be_visible_; }
  bool in_fullscreen_transition() const { return in_fullscreen_transition_; }

  // Whether to run a custom animation for the provided |transition|.
  bool ShouldRunCustomAnimationFor(
      views_bridge_mac::mojom::VisibilityTransition transition) const;

  // Redispatch a keyboard event using the widget's window's CommandDispatcher.
  // Return true if the event is handled.
  bool RedispatchKeyEvent(NSEvent* event);

  // display::DisplayObserver:
  void OnDisplayMetricsChanged(const display::Display& display,
                               uint32_t metrics) override;

  // ui::CATransactionCoordinator::PreCommitObserver:
  bool ShouldWaitInPreCommit() override;
  base::TimeDelta PreCommitTimeout() override;

  // views_bridge_mac::mojom::BridgedNativeWidget:
  void CreateWindow(
      views_bridge_mac::mojom::CreateWindowParamsPtr params) override;
  void SetParent(uint64_t parent_id) override;
  void ShowEmojiPanel() override;
  void InitWindow(views_bridge_mac::mojom::BridgedNativeWidgetInitParamsPtr
                      params) override;
  void InitCompositorView() override;
  void CreateContentView(uint64_t ns_view_id, const gfx::Rect& bounds) override;
  void DestroyContentView() override;
  void CloseWindow() override;
  void CloseWindowNow() override;
  void SetInitialBounds(const gfx::Rect& new_bounds,
                        const gfx::Size& minimum_content_size) override;
  void SetBounds(const gfx::Rect& new_bounds,
                 const gfx::Size& minimum_content_size) override;
  void SetSizeAndCenter(const gfx::Size& content_size,
                        const gfx::Size& minimum_content_size) override;
  void SetVisibilityState(
      views_bridge_mac::mojom::WindowVisibilityState new_state) override;
  void SetAnimationEnabled(bool animation_enabled) override;
  void SetTransitionsToAnimate(
      views_bridge_mac::mojom::VisibilityTransition transitions) override;
  void SetVisibleOnAllSpaces(bool always_visible) override;
  void SetFullscreen(bool fullscreen) override;
  void SetCanAppearInExistingFullscreenSpaces(
      bool can_appear_in_existing_fullscreen_spaces) override;
  void SetMiniaturized(bool miniaturized) override;
  void SetSizeConstraints(const gfx::Size& min_size,
                          const gfx::Size& max_size,
                          bool is_resizable,
                          bool is_maximizable) override;
  void SetOpacity(float opacity) override;
  void SetContentAspectRatio(const gfx::SizeF& aspect_ratio) override;
  void SetCALayerParams(const gfx::CALayerParams& ca_layer_params) override;
  void SetWindowTitle(const base::string16& title) override;
  void MakeFirstResponder() override;
  void ClearTouchBar() override;
  void UpdateTooltip() override;
  void AcquireCapture() override;
  void ReleaseCapture() override;
  void RedispatchKeyEvent(uint64_t type,
                          uint64_t modifier_flags,
                          double timestamp,
                          const base::string16& characters,
                          const base::string16& characters_ignoring_modifiers,
                          uint32_t key_code) override;

  // Return true if [NSApp updateWindows] needs to be called after updating the
  // TextInputClient.
  bool NeedsUpdateWindows();

  // Compute the window and content size, and forward them to |host_|. This will
  // update widget and compositor size.
  void UpdateWindowGeometry();

  // The offset in screen pixels for positioning child windows owned by |this|.
  gfx::Vector2d GetChildWindowOffset() const;

 private:
  friend class test::BridgedNativeWidgetTestApi;

  // Closes all child windows. BridgedNativeWidgetImpl children will be
  // destroyed.
  void RemoveOrDestroyChildren();

  // Remove the specified child window without closing it.
  void RemoveChildWindow(BridgedNativeWidgetImpl* child);

  // Notify descendants of a visibility change.
  void NotifyVisibilityChangeDown();

  // Query the display properties of the monitor that |window_| is on, and
  // forward them to |host_|.
  void UpdateWindowDisplay();

  // Return true if the delegate's modal type is window-modal. These display as
  // a native window "sheet", and have a different lifetime to regular windows.
  bool IsWindowModalSheet() const;

  // Show the window using -[NSApp beginSheet:..], modal for the parent window.
  void ShowAsModalSheet();

  // Returns true if capture exists and is currently active.
  bool HasCapture();

  // CocoaMouseCaptureDelegate:
  void PostCapturedEvent(NSEvent* event) override;
  void OnMouseCaptureLost() override;
  NSWindow* GetWindow() const override;

  const uint64_t id_;
  BridgedNativeWidgetHost* const host_;               // Weak. Owns this.
  BridgedNativeWidgetHostHelper* const host_helper_;  // Weak, owned by |host_|.
  views_bridge_mac::mojom::TextInputHost* const
      text_input_host_;  // Weak, owned by |host_|.

  base::scoped_nsobject<NativeWidgetMacNSWindow> window_;
  base::scoped_nsobject<ViewsNSWindowDelegate> window_delegate_;
  base::scoped_nsobject<NSObject<CommandDispatcherDelegate>>
      window_command_dispatcher_delegate_;

  base::scoped_nsobject<BridgedContentView> bridged_view_;
  std::unique_ptr<ui::ScopedNSViewIdMapping> bridged_view_id_mapping_;
  base::scoped_nsobject<ModalShowAnimationWithLayer> show_animation_;
  std::unique_ptr<CocoaMouseCapture> mouse_capture_;
  std::unique_ptr<CocoaWindowMoveLoop> window_move_loop_;
  ui::ModalType modal_type_ = ui::MODAL_TYPE_NONE;
  bool is_translucent_window_ = false;
  bool widget_is_top_level_ = false;
  bool position_window_in_screen_coords_ = false;

  BridgedNativeWidgetImpl* parent_ = nullptr;  // Weak. If non-null, owns this.
  std::vector<BridgedNativeWidgetImpl*> child_windows_;

  // The size of the content area of the window most recently sent to |host_|
  // (and its compositor).
  gfx::Size content_dip_size_;

  // The size of the frame most recently *received from* the compositor. Note
  // that during resize (and showing new windows), this will lag behind
  // |content_dip_size_|, which is the frame size most recently *sent to* the
  // compositor.
  gfx::Size compositor_frame_dip_size_;
  std::unique_ptr<ui::DisplayCALayerTree> display_ca_layer_tree_;

  // Tracks the bounds when the window last started entering fullscreen. Used to
  // provide an answer for GetRestoredBounds(), but not ever sent to Cocoa (it
  // has its own copy, but doesn't provide access to it).
  gfx::Rect bounds_before_fullscreen_;

  // The transition types to animate when not relying on native NSWindow
  // animation behaviors.
  views_bridge_mac::mojom::VisibilityTransition transitions_to_animate_ =
      views_bridge_mac::mojom::VisibilityTransition::kBoth;

  // Whether this window wants to be fullscreen. If a fullscreen animation is in
  // progress then it might not be actually fullscreen.
  bool target_fullscreen_state_ = false;

  // Whether this window is in a fullscreen transition, and the fullscreen state
  // can not currently be changed.
  bool in_fullscreen_transition_ = false;

  // Stores the value last read from -[NSWindow isVisible], to detect visibility
  // changes.
  bool window_visible_ = false;

  // If true, the window is either visible, or wants to be visible but is
  // currently hidden due to having a hidden parent.
  bool wants_to_be_visible_ = false;

  // If true, then ignore interactions with CATransactionCoordinator until the
  // first frame arrives.
  bool ca_transaction_sync_suppressed_ = false;

  // If true, the window has been made visible or changed shape and the window
  // shadow needs to be invalidated when a frame is received for the new shape.
  bool invalidate_shadow_on_frame_swap_ = false;

  mojo::AssociatedBinding<views_bridge_mac::mojom::BridgedNativeWidget>
      bridge_mojo_binding_;
  DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetImpl);
};

}  // namespace views

#endif  // UI_VIEWS_BRIDGE_MAC_BRIDGED_NATIVE_WIDGET_IMPL_H_
