// Copyright (c) 2012 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.

#import <Cocoa/Cocoa.h>

#import "content/browser/accessibility/browser_accessibility_mac.h"

#import "content/browser/accessibility/browser_accessibility_cocoa.h"
#include "content/browser/accessibility/browser_accessibility_manager_mac.h"

namespace content {

// Static.
BrowserAccessibility* BrowserAccessibility::Create() {
  return new BrowserAccessibilityMac();
}

BrowserAccessibilityMac::BrowserAccessibilityMac()
    : browser_accessibility_cocoa_(NULL) {}

bool BrowserAccessibilityMac::IsNative() const {
  return true;
}

void BrowserAccessibilityMac::NativeReleaseReference() {
  // Detach this object from |browser_accessibility_cocoa_| so it
  // no longer has a pointer to this object.
  [browser_accessibility_cocoa_ detach];
  // Now, release it - but at this point, other processes may have a
  // reference to the cocoa object.
  [browser_accessibility_cocoa_ release];
  // Finally, it's safe to delete this since we've detached.
  delete this;
}

void BrowserAccessibilityMac::OnDataChanged() {
  BrowserAccessibility::OnDataChanged();

  if (browser_accessibility_cocoa_) {
    [browser_accessibility_cocoa_ childrenChanged];
    return;
  }

  // We take ownership of the Cocoa object here.
  browser_accessibility_cocoa_ =
      [[BrowserAccessibilityCocoa alloc] initWithObject:this];
}

uint32_t BrowserAccessibilityMac::PlatformChildCount() const {
  uint32_t child_count = BrowserAccessibility::PlatformChildCount();

  // If this is a table, include the extra fake nodes generated by
  // AXTableInfo, for the column nodes and the table header container, all of
  // which are only important on macOS.
  const std::vector<ui::AXNode*>* extra_mac_nodes = node()->GetExtraMacNodes();
  if (!extra_mac_nodes)
    return child_count;

  return child_count + extra_mac_nodes->size();
}

BrowserAccessibility* BrowserAccessibilityMac::PlatformGetChild(
    uint32_t child_index) const {
  uint32_t child_count = BrowserAccessibility::PlatformChildCount();
  if (child_index < child_count)
    return BrowserAccessibility::PlatformGetChild(child_index);

  // If this is a table, include the extra fake nodes generated by
  // AXTableInfo, for the column nodes and the table header container, all of
  // which are only important on macOS.
  const std::vector<ui::AXNode*>* extra_mac_nodes = node()->GetExtraMacNodes();
  if (!extra_mac_nodes)
    return nullptr;

  child_index -= child_count;
  if (child_index < extra_mac_nodes->size())
    return manager_->GetFromAXNode((*extra_mac_nodes)[child_index]);

  return nullptr;
}

const BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa(
    const BrowserAccessibility* obj) {
  DCHECK(obj);
  DCHECK(obj->IsNative());
  return static_cast<const BrowserAccessibilityMac*>(obj)->native_view();
}

BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa(
    BrowserAccessibility* obj) {
  DCHECK(obj);
  DCHECK(obj->IsNative());
  return static_cast<BrowserAccessibilityMac*>(obj)->native_view();
}

}  // namespace content
