// 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/FlutterTextInputModel.h"

static NSString* const kTextAffinityDownstream = @"TextAffinity.downstream";
static NSString* const kTextAffinityUpstream = @"TextAffinity.upstream";

static NSString* const kTextInputAction = @"inputAction";
static NSString* const kTextInputType = @"inputType";
static NSString* const kTextInputTypeName = @"name";

static NSString* const kSelectionBaseKey = @"selectionBase";
static NSString* const kSelectionExtentKey = @"selectionExtent";
static NSString* const kSelectionAffinityKey = @"selectionAffinity";
static NSString* const kSelectionIsDirectionalKey = @"selectionIsDirectional";
static NSString* const kComposingBaseKey = @"composingBase";
static NSString* const kComposingExtentKey = @"composingExtent";
static NSString* const kTextKey = @"text";

/**
 * These three static methods are necessary because Cocoa and Flutter have different idioms for
 * signaling an empty range: Flutter uses {-1, -1} while Cocoa uses {NSNotFound, 0}. Also,
 * despite the name, the "extent" fields are actually end indices, not lengths.
 */

/**
 * Updates a range given base and extent fields.
 */
static NSRange UpdateRangeFromBaseExtent(NSNumber* base, NSNumber* extent, NSRange range) {
  if (base == nil || extent == nil) {
    return range;
  }
  if (base.intValue == -1 && extent.intValue == -1) {
    range.location = NSNotFound;
    range.length = 0;
  } else {
    range.location = [base unsignedLongValue];
    range.length = [extent unsignedLongValue] - range.location;
  }
  return range;
}

/**
 * Returns the appropriate base field for a given range.
 */
static long GetBaseForRange(NSRange range) {
  if (range.location == NSNotFound) {
    return -1;
  }
  return range.location;
}

/**
 * Returns the appropriate extent field for a given range.
 */
static long GetExtentForRange(NSRange range) {
  if (range.location == NSNotFound) {
    return -1;
  }
  return range.location + range.length;
}

@implementation FlutterTextInputModel

- (instancetype)initWithClientID:(NSNumber*)clientID configuration:(NSDictionary*)config {
  self = [super init];
  if (self != nil) {
    _clientID = clientID;
    _inputAction = config[kTextInputAction];
    // There's more information that can be used from this dictionary.
    // Add more as needed.
    NSDictionary* inputTypeInfo = config[kTextInputType];
    _inputType = inputTypeInfo[kTextInputTypeName];
    if (!_clientID || !_inputAction || !_inputType) {
      NSLog(@"Missing arguments for %@ init.", [self class]);
      return nil;
    }

    _text = [[NSMutableString alloc] init];
    _selectedRange = NSMakeRange(NSNotFound, 0);
    _markedRange = NSMakeRange(NSNotFound, 0);
    _textAffinity = FlutterTextAffinityUpstream;
  }
  return self;
}

- (NSDictionary*)state {
  NSString* const textAffinity = (_textAffinity == FlutterTextAffinityUpstream)
                                     ? kTextAffinityUpstream
                                     : kTextAffinityDownstream;
  NSDictionary* state = @{
    kSelectionBaseKey : @(GetBaseForRange(_selectedRange)),
    kSelectionExtentKey : @(GetExtentForRange(_selectedRange)),
    kSelectionAffinityKey : textAffinity,
    kSelectionIsDirectionalKey : @NO,
    kComposingBaseKey : @(GetBaseForRange(_markedRange)),
    kComposingExtentKey : @(GetExtentForRange(_markedRange)),
    kTextKey : _text
  };
  return state;
}

- (void)setState:(NSDictionary*)state {
  if (state == nil)
    return;

  _selectedRange = UpdateRangeFromBaseExtent(state[kSelectionBaseKey], state[kSelectionExtentKey],
                                             _selectedRange);
  NSString* selectionAffinity = state[kSelectionAffinityKey];
  if (selectionAffinity != nil) {
    _textAffinity = [selectionAffinity isEqualToString:kTextAffinityUpstream]
                        ? FlutterTextAffinityUpstream
                        : FlutterTextAffinityDownstream;
  }
  _markedRange =
      UpdateRangeFromBaseExtent(state[kComposingBaseKey], state[kComposingExtentKey], _markedRange);
  NSString* text = state[kTextKey];
  if (text != nil)
    [_text setString:text];
}

@end
