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

#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObject.h"

#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"

#include "flutter/third_party/accessibility/ax/ax_action_data.h"
#include "flutter/third_party/accessibility/gfx/geometry/rect_conversions.h"
#include "flutter/third_party/accessibility/gfx/mac/coordinate_conversion.h"

#pragma mark - FlutterTextFieldCell
/**
 * A convenient class that can be used to set a custom field editor for an
 * NSTextField.
 *
 * The FlutterTextField uses this class set the FlutterTextInputPlugin as
 * its field editor.
 */
@interface FlutterTextFieldCell : NSTextFieldCell

/**
 * Initializes the NSCell for the input NSTextField.
 */
- (instancetype)initWithTextField:(NSTextField*)textField fieldEditor:(NSTextView*)editor;

@end

@implementation FlutterTextFieldCell {
  NSTextView* _editor;
}

#pragma mark - Private

- (instancetype)initWithTextField:(NSTextField*)textField fieldEditor:(NSTextView*)editor {
  self = [super initTextCell:textField.stringValue];
  if (self) {
    _editor = editor;
    [self setControlView:textField];
    // Read-only text fields are sent to the mac embedding as static
    // text. This text field must be editable and selectable at this
    // point.
    self.editable = YES;
    self.selectable = YES;
  }
  return self;
}

#pragma mark - NSCell

- (NSTextView*)fieldEditorForView:(NSView*)controlView {
  return _editor;
}

@end

#pragma mark - FlutterTextField

@implementation FlutterTextField {
  flutter::FlutterTextPlatformNode* _node;
  FlutterTextInputPlugin* _plugin;
}

#pragma mark - Public

- (instancetype)initWithPlatformNode:(flutter::FlutterTextPlatformNode*)node
                         fieldEditor:(FlutterTextInputPlugin*)plugin {
  self = [super initWithFrame:NSZeroRect];
  if (self) {
    _node = node;
    _plugin = plugin;
    [self setCell:[[FlutterTextFieldCell alloc] initWithTextField:self fieldEditor:plugin]];
  }
  return self;
}

- (void)updateString:(NSString*)string withSelection:(NSRange)selection {
  NSAssert(_plugin.client == self,
           @"Can't update FlutterTextField when it is not the first responder");
  if (![[self stringValue] isEqualToString:string]) {
    [self setStringValue:string];
  }
  if (!NSEqualRanges(_plugin.selectedRange, selection)) {
    [_plugin setSelectedRange:selection];
  }
}

#pragma mark - NSView

- (NSRect)frame {
  return _node->GetFrame();
}

#pragma mark - NSAccessibilityProtocol

- (void)setAccessibilityFocused:(BOOL)isFocused {
  [super setAccessibilityFocused:isFocused];
  ui::AXActionData data;
  data.action = isFocused ? ax::mojom::Action::kFocus : ax::mojom::Action::kBlur;
  _node->GetDelegate()->AccessibilityPerformAction(data);
}

#pragma mark - NSResponder

- (BOOL)becomeFirstResponder {
  if (!_plugin) {
    return NO;
  }
  if (_plugin.client == self && [_plugin isFirstResponder]) {
    // This text field is already the first responder.
    return YES;
  }
  BOOL result = [super becomeFirstResponder];
  if (result) {
    _plugin.client = self;
    // The default implementation of the becomeFirstResponder will change the
    // text editing state. Need to manually set it back.
    NSString* textValue = @(_node->GetStringAttribute(ax::mojom::StringAttribute::kValue).data());
    int start = _node->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart);
    int end = _node->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd);
    NSAssert((start >= 0 && end >= 0) || (start == -1 && end == -1), @"selection is invalid");
    NSRange selection;
    if (start >= 0 && end >= 0) {
      selection = NSMakeRange(MIN(start, end), ABS(end - start));
    } else {
      // The native behavior is to place the cursor at the end of the string if
      // there is no selection.
      selection = NSMakeRange([self stringValue].length, 0);
    }
    [self updateString:textValue withSelection:selection];
  }
  return result;
}

- (BOOL)resignFirstResponder {
  BOOL result = [super resignFirstResponder];
  if (result && _plugin.client == self) {
    _plugin.client = nil;
  }
  return result;
}

#pragma mark - NSObject

- (void)dealloc {
  [self resignFirstResponder];
}

@end

namespace flutter {

FlutterTextPlatformNode::FlutterTextPlatformNode(FlutterPlatformNodeDelegate* delegate,
                                                 __weak FlutterViewController* view_controller) {
  Init(delegate);
  view_controller_ = view_controller;
  appkit_text_field_ =
      [[FlutterTextField alloc] initWithPlatformNode:this
                                         fieldEditor:view_controller.textInputPlugin];
  appkit_text_field_.bezeled = NO;
  appkit_text_field_.drawsBackground = NO;
  appkit_text_field_.bordered = NO;
  appkit_text_field_.focusRingType = NSFocusRingTypeNone;
}

FlutterTextPlatformNode::~FlutterTextPlatformNode() {
  EnsureDetachedFromView();
}

gfx::NativeViewAccessible FlutterTextPlatformNode::GetNativeViewAccessible() {
  if (EnsureAttachedToView()) {
    return appkit_text_field_;
  }
  return nil;
}

NSRect FlutterTextPlatformNode::GetFrame() {
  if (!view_controller_.viewLoaded) {
    return NSZeroRect;
  }
  FlutterPlatformNodeDelegate* delegate = static_cast<FlutterPlatformNodeDelegate*>(GetDelegate());
  bool offscreen;
  auto bridge_ptr = delegate->GetOwnerBridge().lock();
  gfx::RectF bounds = bridge_ptr->RelativeToGlobalBounds(delegate->GetAXNode(), offscreen, true);

  // Converts to NSRect to use NSView rect conversion.
  NSRect ns_local_bounds = NSMakeRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
  // The macOS XY coordinates start at bottom-left and increase toward top-right,
  // which is different from the Flutter's XY coordinates that start at top-left
  // increasing to bottom-right. Flip the y coordinate to convert from Flutter
  // coordinates to macOS coordinates.
  ns_local_bounds.origin.y = -ns_local_bounds.origin.y - ns_local_bounds.size.height;
  NSRect ns_view_bounds = [view_controller_.flutterView convertRectFromBacking:ns_local_bounds];
  return [view_controller_.flutterView convertRect:ns_view_bounds toView:nil];
}

bool FlutterTextPlatformNode::EnsureAttachedToView() {
  if (!view_controller_.viewLoaded) {
    return false;
  }
  if ([appkit_text_field_ isDescendantOf:view_controller_.view]) {
    return true;
  }
  [view_controller_.view addSubview:appkit_text_field_
                         positioned:NSWindowBelow
                         relativeTo:view_controller_.flutterView];
  return true;
}

void FlutterTextPlatformNode::EnsureDetachedFromView() {
  [appkit_text_field_ removeFromSuperview];
}

}
