// 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::AXUniqueId& GetUniqueId() const override { return unique_id_; }

  // |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_;
  ui::AXUniqueId unique_id_;
};

}  // namespace flutter

#endif  // FLUTTER_SHELL_PLATFORM_COMMON_FLUTTER_PLATFORM_NODE_DELEGATE_H_
