// Copyright 2013 The Flutter 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 FLUTTER_SHELL_PLATFORM_COMMON_FLUTTER_PLATFORM_NODE_DELEGATE_H_
#define FLUTTER_SHELL_PLATFORM_COMMON_FLUTTER_PLATFORM_NODE_DELEGATE_H_

#include "flutter/fml/mapping.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/third_party/accessibility/ax/ax_event_generator.h"
#include "flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.h"

namespace flutter {

typedef ui::AXNode::AXID AccessibilityNodeId;

//------------------------------------------------------------------------------
/// The platform node delegate to be used in accessibility bridge. This
/// class is responsible for providing native accessibility object with
/// appropriate information, such as accessibility label/value/bounds.
///
/// While most methods have default implementations and are ready to be used
/// as-is, the subclasses must override the GetNativeViewAccessible to return
/// native accessibility objects. To do that, subclasses should create and
/// maintain AXPlatformNode[s] which delegate their accessibility attributes to
/// this class.
///
/// For desktop platforms, subclasses also need to override the GetBoundsRect
/// to apply window-to-screen transform.
///
/// This class transforms bounds assuming the device pixel ratio is 1.0. See
/// the https://github.com/flutter/flutter/issues/74283 for more information.
class FlutterPlatformNodeDelegate : public ui::AXPlatformNodeDelegateBase {
 public:
  //----------------------------------------------------------------------------
  /// The required interface to be able to own the flutter platform node
  /// delegate.
  class OwnerBridge {
   public:
    virtual ~OwnerBridge() = default;

    //---------------------------------------------------------------------------
    /// @brief      Gets the rectangular bounds of the ax node relative to
    ///             global coordinate
    ///
    /// @param[in]  node        The ax node to look up.
    /// @param[in]  offscreen   the bool reference to hold the result whether
    ///                         the ax node is outside of its ancestors' bounds.
    /// @param[in]  clip_bounds whether to clip the result if the ax node cannot
    ///                         be fully contained in its ancestors' bounds.
    virtual gfx::RectF RelativeToGlobalBounds(const ui::AXNode* node,
                                              bool& offscreen,
                                              bool clip_bounds) = 0;

   protected:
    friend class FlutterPlatformNodeDelegate;

    //---------------------------------------------------------------------------
    /// @brief      Dispatch accessibility action back to the Flutter framework.
    ///             These actions are generated in the native accessibility
    ///             system when users interact with the assistive technologies.
    ///             For example, a
    ///             FlutterSemanticsAction::kFlutterSemanticsActionTap is
    ///             fired when user click or touch the screen.
    ///
    /// @param[in]  target              The semantics node id of the action
    ///                                 target.
    /// @param[in]  action              The generated flutter semantics action.
    /// @param[in]  data                Additional data associated with the
    ///                                 action.
    virtual void DispatchAccessibilityAction(AccessibilityNodeId target,
                                             FlutterSemanticsAction action,
                                             fml::MallocMapping data) = 0;

    //---------------------------------------------------------------------------
    /// @brief      Get the native accessibility node with the given id.
    ///
    /// @param[in]  id           The id of the native accessibility node you
    ///                          want to retrieve.
    virtual gfx::NativeViewAccessible GetNativeAccessibleFromId(
        AccessibilityNodeId id) = 0;

    //---------------------------------------------------------------------------
    /// @brief      Get the last id of the node that received accessibility
    ///             focus.
    virtual AccessibilityNodeId GetLastFocusedId() = 0;

    //---------------------------------------------------------------------------
    /// @brief      Update the id of the node that is currently foucsed by the
    ///             native accessibility system.
    ///
    /// @param[in]  node_id     The id of the focused node.
    virtual void SetLastFocusedId(AccessibilityNodeId node_id) = 0;
  };

  FlutterPlatformNodeDelegate();

  // |ui::AXPlatformNodeDelegateBase|
  virtual ~FlutterPlatformNodeDelegate() override;

  // |ui::AXPlatformNodeDelegateBase|
  const ui::AXNodeData& GetData() const override;

  // |ui::AXPlatformNodeDelegateBase|
  bool AccessibilityPerformAction(const ui::AXActionData& data) override;

  // |ui::AXPlatformNodeDelegateBase|
  gfx::NativeViewAccessible GetParent() override;

  // |ui::AXPlatformNodeDelegateBase|
  gfx::NativeViewAccessible GetFocus() override;

  // |ui::AXPlatformNodeDelegateBase|
  int GetChildCount() const override;

  // |ui::AXPlatformNodeDelegateBase|
  gfx::NativeViewAccessible ChildAtIndex(int index) override;

  // |ui::AXPlatformNodeDelegateBase|
  gfx::Rect GetBoundsRect(
      const ui::AXCoordinateSystem coordinate_system,
      const ui::AXClippingBehavior clipping_behavior,
      ui::AXOffscreenResult* offscreen_result) const override;

  //------------------------------------------------------------------------------
  /// @brief      Called only once, immediately after construction. The
  ///             constructor doesn't take any arguments because in the Windows
  ///             subclass we use a special function to construct a COM object.
  ///             Subclasses must call super.
  virtual void Init(std::weak_ptr<OwnerBridge> bridge, ui::AXNode* node);

  //------------------------------------------------------------------------------
  /// @brief      Gets the underlying ax node for this platform node delegate.
  ui::AXNode* GetAXNode() const;

  //------------------------------------------------------------------------------
  /// @brief      Gets the owner of this platform node delegate. This is useful
  ///             when you want to get the information about surrounding nodes
  ///             of this platform node delegate, e.g. the global rect of this
  ///             platform node delegate. This pointer is only safe in the
  ///             platform thread.
  std::weak_ptr<OwnerBridge> GetOwnerBridge() const;

 private:
  ui::AXNode* ax_node_;
  std::weak_ptr<OwnerBridge> bridge_;
};

}  // namespace flutter

#endif  // FLUTTER_SHELL_PLATFORM_COMMON_FLUTTER_PLATFORM_NODE_DELEGATE_H_
