// 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.

#include <oleacc.h>

#include "flutter/shell/platform/windows/flutter_platform_node_delegate_windows.h"

#include "flutter/shell/platform/windows/accessibility_bridge_windows.h"
#include "flutter/shell/platform/windows/flutter_windows_view.h"
#include "flutter/third_party/accessibility/ax/ax_clipping_behavior.h"
#include "flutter/third_party/accessibility/ax/ax_coordinate_system.h"

namespace flutter {

FlutterPlatformNodeDelegateWindows::FlutterPlatformNodeDelegateWindows(
    std::weak_ptr<AccessibilityBridge> bridge,
    FlutterWindowsView* view)
    : bridge_(bridge), view_(view) {
  assert(!bridge_.expired());
  assert(view_);
}

FlutterPlatformNodeDelegateWindows::~FlutterPlatformNodeDelegateWindows() {
  if (ax_platform_node_) {
    ax_platform_node_->Destroy();
  }
}

// |ui::AXPlatformNodeDelegate|
void FlutterPlatformNodeDelegateWindows::Init(std::weak_ptr<OwnerBridge> bridge,
                                              ui::AXNode* node) {
  FlutterPlatformNodeDelegate::Init(bridge, node);
  ax_platform_node_ = ui::AXPlatformNode::Create(this);
  assert(ax_platform_node_);
}

// |ui::AXPlatformNodeDelegate|
gfx::NativeViewAccessible
FlutterPlatformNodeDelegateWindows::GetNativeViewAccessible() {
  assert(ax_platform_node_);
  return ax_platform_node_->GetNativeViewAccessible();
}

// |ui::AXPlatformNodeDelegate|
gfx::NativeViewAccessible FlutterPlatformNodeDelegateWindows::HitTestSync(
    int screen_physical_pixel_x,
    int screen_physical_pixel_y) const {
  // If this node doesn't contain the point, return.
  ui::AXOffscreenResult result;
  gfx::Rect rect = GetBoundsRect(ui::AXCoordinateSystem::kScreenPhysicalPixels,
                                 ui::AXClippingBehavior::kUnclipped, &result);
  gfx::Point screen_point(screen_physical_pixel_x, screen_physical_pixel_y);
  if (!rect.Contains(screen_point)) {
    return nullptr;
  }

  // If any child in this node's subtree contains the point, return that child.
  auto bridge = bridge_.lock();
  assert(bridge);
  for (const ui::AXNode* child : GetAXNode()->children()) {
    std::shared_ptr<FlutterPlatformNodeDelegateWindows> win_delegate =
        std::static_pointer_cast<FlutterPlatformNodeDelegateWindows>(
            bridge->GetFlutterPlatformNodeDelegateFromID(child->id()).lock());
    assert(win_delegate);
    auto hit_view = win_delegate->HitTestSync(screen_physical_pixel_x,
                                              screen_physical_pixel_y);
    if (hit_view) {
      return hit_view;
    }
  }

  // If no children contain the point, but this node does, return this node.
  return ax_platform_node_->GetNativeViewAccessible();
}

// |FlutterPlatformNodeDelegate|
gfx::Rect FlutterPlatformNodeDelegateWindows::GetBoundsRect(
    const ui::AXCoordinateSystem coordinate_system,
    const ui::AXClippingBehavior clipping_behavior,
    ui::AXOffscreenResult* offscreen_result) const {
  gfx::Rect bounds = FlutterPlatformNodeDelegate::GetBoundsRect(
      coordinate_system, clipping_behavior, offscreen_result);
  POINT origin{bounds.x(), bounds.y()};
  POINT extent{bounds.x() + bounds.width(), bounds.y() + bounds.height()};
  ClientToScreen(view_->GetPlatformWindow(), &origin);
  ClientToScreen(view_->GetPlatformWindow(), &extent);
  return gfx::Rect(origin.x, origin.y, extent.x - origin.x,
                   extent.y - origin.y);
}

void FlutterPlatformNodeDelegateWindows::DispatchWinAccessibilityEvent(
    DWORD event_type) {
  HWND hwnd = view_->GetPlatformWindow();
  if (!hwnd) {
    return;
  }
  assert(ax_platform_node_);
  ::NotifyWinEvent(event_type, hwnd, OBJID_CLIENT,
                   -ax_platform_node_->GetUniqueId());
}

void FlutterPlatformNodeDelegateWindows::SetFocus() {
  VARIANT varchild{};
  varchild.vt = VT_I4;
  varchild.lVal = CHILDID_SELF;
  GetNativeViewAccessible()->accSelect(SELFLAG_TAKEFOCUS, varchild);
}

}  // namespace flutter
