// 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 "flutter/shell/platform/linux/fl_text_input_plugin.h"

#include <gtk/gtk.h>

#include "flutter/shell/platform/common/text_editing_delta.h"
#include "flutter/shell/platform/common/text_input_model.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_method_codec.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h"

static constexpr char kChannelName[] = "flutter/textinput";

static constexpr char kBadArgumentsError[] = "Bad Arguments";

static constexpr char kSetClientMethod[] = "TextInput.setClient";
static constexpr char kShowMethod[] = "TextInput.show";
static constexpr char kSetEditingStateMethod[] = "TextInput.setEditingState";
static constexpr char kClearClientMethod[] = "TextInput.clearClient";
static constexpr char kHideMethod[] = "TextInput.hide";
static constexpr char kUpdateEditingStateMethod[] =
    "TextInputClient.updateEditingState";
static constexpr char kUpdateEditingStateWithDeltasMethod[] =
    "TextInputClient.updateEditingStateWithDeltas";
static constexpr char kPerformActionMethod[] = "TextInputClient.performAction";
static constexpr char kSetEditableSizeAndTransform[] =
    "TextInput.setEditableSizeAndTransform";
static constexpr char kSetMarkedTextRect[] = "TextInput.setMarkedTextRect";

static constexpr char kInputActionKey[] = "inputAction";
static constexpr char kTextInputTypeKey[] = "inputType";
static constexpr char kEnableDeltaModel[] = "enableDeltaModel";
static constexpr char kTextInputTypeNameKey[] = "name";
static constexpr char kTextKey[] = "text";
static constexpr char kSelectionBaseKey[] = "selectionBase";
static constexpr char kSelectionExtentKey[] = "selectionExtent";
static constexpr char kSelectionAffinityKey[] = "selectionAffinity";
static constexpr char kSelectionIsDirectionalKey[] = "selectionIsDirectional";
static constexpr char kComposingBaseKey[] = "composingBase";
static constexpr char kComposingExtentKey[] = "composingExtent";

static constexpr char kTransform[] = "transform";

static constexpr char kTextAffinityDownstream[] = "TextAffinity.downstream";
static constexpr char kMultilineInputType[] = "TextInputType.multiline";
static constexpr char kNoneInputType[] = "TextInputType.none";

static constexpr char kNewlineInputAction[] = "TextInputAction.newline";

static constexpr int64_t kClientIdUnset = -1;

typedef enum {
  kFlTextInputTypeText,
  // Send newline when multi-line and enter is pressed.
  kFlTextInputTypeMultiline,
  // The input method is not shown at all.
  kFlTextInputTypeNone,
} FlTextInputType;

struct FlTextInputPluginPrivate {
  GObject parent_instance;

  FlMethodChannel* channel;

  // Client ID provided by Flutter to report events with.
  int64_t client_id;

  // Input action to perform when enter pressed.
  gchar* input_action;

  // The type of the input method.
  FlTextInputType input_type;

  // Whether to enable that the engine sends text input updates to the framework
  // as TextEditingDeltas or as one TextEditingValue.
  // For more information on the delta model, see:
  // https://master-api.flutter.dev/flutter/services/TextInputConfiguration/enableDeltaModel.html
  gboolean enable_delta_model;

  // Input method.
  GtkIMContext* im_context;

  FlTextInputViewDelegate* view_delegate;

  flutter::TextInputModel* text_model;

  // A 4x4 matrix that maps from `EditableText` local coordinates to the
  // coordinate system of `PipelineOwner.rootNode`.
  double editabletext_transform[4][4];

  // The smallest rect, in local coordinates, of the text in the composing
  // range, or of the caret in the case where there is no current composing
  // range. This value is updated via `TextInput.setMarkedTextRect` messages
  // over the text input channel.
  GdkRectangle composing_rect;
};

G_DEFINE_TYPE_WITH_PRIVATE(FlTextInputPlugin,
                           fl_text_input_plugin,
                           G_TYPE_OBJECT)

// Completes method call and returns TRUE if the call was successful.
static gboolean finish_method(GObject* object,
                              GAsyncResult* result,
                              GError** error) {
  g_autoptr(FlMethodResponse) response = fl_method_channel_invoke_method_finish(
      FL_METHOD_CHANNEL(object), result, error);
  if (response == nullptr) {
    return FALSE;
  }
  return fl_method_response_get_result(response, error) != nullptr;
}

// Called when a response is received from TextInputClient.updateEditingState()
static void update_editing_state_response_cb(GObject* object,
                                             GAsyncResult* result,
                                             gpointer user_data) {
  g_autoptr(GError) error = nullptr;
  if (!finish_method(object, result, &error)) {
    g_warning("Failed to call %s: %s", kUpdateEditingStateMethod,
              error->message);
  }
}

// Informs Flutter of text input changes.
static void update_editing_state(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));

  g_autoptr(FlValue) args = fl_value_new_list();
  fl_value_append_take(args, fl_value_new_int(priv->client_id));
  g_autoptr(FlValue) value = fl_value_new_map();

  flutter::TextRange selection = priv->text_model->selection();
  fl_value_set_string_take(
      value, kTextKey,
      fl_value_new_string(priv->text_model->GetText().c_str()));
  fl_value_set_string_take(value, kSelectionBaseKey,
                           fl_value_new_int(selection.base()));
  fl_value_set_string_take(value, kSelectionExtentKey,
                           fl_value_new_int(selection.extent()));

  int composing_base = -1;
  int composing_extent = -1;
  if (!priv->text_model->composing_range().collapsed()) {
    composing_base = priv->text_model->composing_range().base();
    composing_extent = priv->text_model->composing_range().extent();
  }
  fl_value_set_string_take(value, kComposingBaseKey,
                           fl_value_new_int(composing_base));
  fl_value_set_string_take(value, kComposingExtentKey,
                           fl_value_new_int(composing_extent));

  // The following keys are not implemented and set to default values.
  fl_value_set_string_take(value, kSelectionAffinityKey,
                           fl_value_new_string(kTextAffinityDownstream));
  fl_value_set_string_take(value, kSelectionIsDirectionalKey,
                           fl_value_new_bool(FALSE));

  fl_value_append(args, value);

  fl_method_channel_invoke_method(priv->channel, kUpdateEditingStateMethod,
                                  args, nullptr,
                                  update_editing_state_response_cb, self);
}

// Informs Flutter of text input changes by passing just the delta.
static void update_editing_state_with_delta(FlTextInputPlugin* self,
                                            flutter::TextEditingDelta* delta) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));

  g_autoptr(FlValue) args = fl_value_new_list();
  fl_value_append_take(args, fl_value_new_int(priv->client_id));

  g_autoptr(FlValue) deltaValue = fl_value_new_map();
  fl_value_set_string_take(deltaValue, "oldText",
                           fl_value_new_string(delta->old_text().c_str()));

  fl_value_set_string_take(deltaValue, "deltaText",
                           fl_value_new_string(delta->delta_text().c_str()));

  fl_value_set_string_take(deltaValue, "deltaStart",
                           fl_value_new_int(delta->delta_start()));

  fl_value_set_string_take(deltaValue, "deltaEnd",
                           fl_value_new_int(delta->delta_end()));

  flutter::TextRange selection = priv->text_model->selection();
  fl_value_set_string_take(deltaValue, "selectionBase",
                           fl_value_new_int(selection.base()));

  fl_value_set_string_take(deltaValue, "selectionExtent",
                           fl_value_new_int(selection.extent()));

  fl_value_set_string_take(deltaValue, "selectionAffinity",
                           fl_value_new_string(kTextAffinityDownstream));

  fl_value_set_string_take(deltaValue, "selectionIsDirectional",
                           fl_value_new_bool(FALSE));

  int composing_base = -1;
  int composing_extent = -1;
  if (!priv->text_model->composing_range().collapsed()) {
    composing_base = priv->text_model->composing_range().base();
    composing_extent = priv->text_model->composing_range().extent();
  }
  fl_value_set_string_take(deltaValue, "composingBase",
                           fl_value_new_int(composing_base));
  fl_value_set_string_take(deltaValue, "composingExtent",
                           fl_value_new_int(composing_extent));

  g_autoptr(FlValue) deltas = fl_value_new_list();
  fl_value_append(deltas, deltaValue);
  g_autoptr(FlValue) value = fl_value_new_map();
  fl_value_set_string(value, "deltas", deltas);

  fl_value_append(args, value);

  fl_method_channel_invoke_method(
      priv->channel, kUpdateEditingStateWithDeltasMethod, args, nullptr,
      update_editing_state_response_cb, self);
}

// Called when a response is received from TextInputClient.performAction()
static void perform_action_response_cb(GObject* object,
                                       GAsyncResult* result,
                                       gpointer user_data) {
  g_autoptr(GError) error = nullptr;
  if (!finish_method(object, result, &error)) {
    g_warning("Failed to call %s: %s", kPerformActionMethod, error->message);
  }
}

// Inform Flutter that the input has been activated.
static void perform_action(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));

  g_return_if_fail(FL_IS_TEXT_INPUT_PLUGIN(self));
  g_return_if_fail(priv->client_id != 0);
  g_return_if_fail(priv->input_action != nullptr);

  g_autoptr(FlValue) args = fl_value_new_list();
  fl_value_append_take(args, fl_value_new_int(priv->client_id));
  fl_value_append_take(args, fl_value_new_string(priv->input_action));

  fl_method_channel_invoke_method(priv->channel, kPerformActionMethod, args,
                                  nullptr, perform_action_response_cb, self);
}

// Signal handler for GtkIMContext::preedit-start
static void im_preedit_start_cb(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  priv->text_model->BeginComposing();
}

// Signal handler for GtkIMContext::preedit-changed
static void im_preedit_changed_cb(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  std::string text_before_change = priv->text_model->GetText();
  flutter::TextRange composing_before_change =
      priv->text_model->composing_range();
  g_autofree gchar* buf = nullptr;
  gint cursor_offset = 0;
  gtk_im_context_get_preedit_string(priv->im_context, &buf, nullptr,
                                    &cursor_offset);
  if (priv->text_model->composing()) {
    cursor_offset += priv->text_model->composing_range().start();
  } else {
    cursor_offset += priv->text_model->selection().start();
  }
  priv->text_model->UpdateComposingText(buf);
  priv->text_model->SetSelection(flutter::TextRange(cursor_offset));

  if (priv->enable_delta_model) {
    std::string text(buf);
    flutter::TextEditingDelta delta = flutter::TextEditingDelta(
        text_before_change, composing_before_change, text);
    update_editing_state_with_delta(self, &delta);
  } else {
    update_editing_state(self);
  }
}

// Signal handler for GtkIMContext::commit
static void im_commit_cb(FlTextInputPlugin* self, const gchar* text) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  std::string text_before_change = priv->text_model->GetText();
  flutter::TextRange composing_before_change =
      priv->text_model->composing_range();
  flutter::TextRange selection_before_change = priv->text_model->selection();
  gboolean was_composing = priv->text_model->composing();

  priv->text_model->AddText(text);
  if (priv->text_model->composing()) {
    priv->text_model->CommitComposing();
  }

  if (priv->enable_delta_model) {
    flutter::TextRange replace_range =
        was_composing ? composing_before_change : selection_before_change;
    std::unique_ptr<flutter::TextEditingDelta> delta =
        std::make_unique<flutter::TextEditingDelta>(text_before_change,
                                                    replace_range, text);
    update_editing_state_with_delta(self, delta.get());
  } else {
    update_editing_state(self);
  }
}

// Signal handler for GtkIMContext::preedit-end
static void im_preedit_end_cb(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  priv->text_model->EndComposing();
  if (priv->enable_delta_model) {
    flutter::TextEditingDelta delta =
        flutter::TextEditingDelta(priv->text_model->GetText());
    update_editing_state_with_delta(self, &delta);
  } else {
    update_editing_state(self);
  }
}

// Signal handler for GtkIMContext::retrieve-surrounding
static gboolean im_retrieve_surrounding_cb(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  auto text = priv->text_model->GetText();
  size_t cursor_offset = priv->text_model->GetCursorOffset();
  gtk_im_context_set_surrounding(priv->im_context, text.c_str(), -1,
                                 cursor_offset);
  return TRUE;
}

// Signal handler for GtkIMContext::delete-surrounding
static gboolean im_delete_surrounding_cb(FlTextInputPlugin* self,
                                         gint offset,
                                         gint n_chars) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));

  std::string text_before_change = priv->text_model->GetText();
  if (priv->text_model->DeleteSurrounding(offset, n_chars)) {
    if (priv->enable_delta_model) {
      flutter::TextEditingDelta delta = flutter::TextEditingDelta(
          text_before_change, priv->text_model->composing_range(),
          priv->text_model->GetText());
      update_editing_state_with_delta(self, &delta);
    } else {
      update_editing_state(self);
    }
  }
  return TRUE;
}

// Called when the input method client is set up.
static FlMethodResponse* set_client(FlTextInputPlugin* self, FlValue* args) {
  if (fl_value_get_type(args) != FL_VALUE_TYPE_LIST ||
      fl_value_get_length(args) < 2) {
    return FL_METHOD_RESPONSE(fl_method_error_response_new(
        kBadArgumentsError, "Expected 2-element list", nullptr));
  }
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));

  priv->client_id = fl_value_get_int(fl_value_get_list_value(args, 0));
  FlValue* config_value = fl_value_get_list_value(args, 1);
  g_free(priv->input_action);
  FlValue* input_action_value =
      fl_value_lookup_string(config_value, kInputActionKey);
  if (fl_value_get_type(input_action_value) == FL_VALUE_TYPE_STRING) {
    priv->input_action = g_strdup(fl_value_get_string(input_action_value));
  }

  FlValue* enable_delta_model_value =
      fl_value_lookup_string(config_value, kEnableDeltaModel);
  gboolean enable_delta_model = fl_value_get_bool(enable_delta_model_value);
  priv->enable_delta_model = enable_delta_model;

  // Reset the input type, then set only if appropriate.
  priv->input_type = kFlTextInputTypeText;
  FlValue* input_type_value =
      fl_value_lookup_string(config_value, kTextInputTypeKey);
  if (fl_value_get_type(input_type_value) == FL_VALUE_TYPE_MAP) {
    FlValue* input_type_name =
        fl_value_lookup_string(input_type_value, kTextInputTypeNameKey);
    if (fl_value_get_type(input_type_name) == FL_VALUE_TYPE_STRING) {
      const gchar* input_type = fl_value_get_string(input_type_name);
      if (g_strcmp0(input_type, kMultilineInputType) == 0) {
        priv->input_type = kFlTextInputTypeMultiline;
      } else if (g_strcmp0(input_type, kNoneInputType) == 0) {
        priv->input_type = kFlTextInputTypeNone;
      }
    }
  }

  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}

// Hides the input method.
static FlMethodResponse* hide(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  gtk_im_context_focus_out(priv->im_context);

  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}

// Shows the input method.
static FlMethodResponse* show(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  if (priv->input_type == kFlTextInputTypeNone) {
    return hide(self);
  }

  gtk_im_context_focus_in(priv->im_context);

  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}

// Updates the editing state from Flutter.
static FlMethodResponse* set_editing_state(FlTextInputPlugin* self,
                                           FlValue* args) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  const gchar* text =
      fl_value_get_string(fl_value_lookup_string(args, kTextKey));
  priv->text_model->SetText(text);

  int64_t selection_base =
      fl_value_get_int(fl_value_lookup_string(args, kSelectionBaseKey));
  int64_t selection_extent =
      fl_value_get_int(fl_value_lookup_string(args, kSelectionExtentKey));
  // Flutter uses -1/-1 for invalid; translate that to 0/0 for the model.
  if (selection_base == -1 && selection_extent == -1) {
    selection_base = selection_extent = 0;
  }

  priv->text_model->SetText(text);
  priv->text_model->SetSelection(
      flutter::TextRange(selection_base, selection_extent));

  int64_t composing_base =
      fl_value_get_int(fl_value_lookup_string(args, kComposingBaseKey));
  int64_t composing_extent =
      fl_value_get_int(fl_value_lookup_string(args, kComposingExtentKey));
  if (composing_base == -1 && composing_extent == -1) {
    priv->text_model->EndComposing();
  } else {
    size_t composing_start = std::min(composing_base, composing_extent);
    size_t cursor_offset = selection_base - composing_start;
    priv->text_model->SetComposingRange(
        flutter::TextRange(composing_base, composing_extent), cursor_offset);
  }

  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}

// Called when the input method client is complete.
static FlMethodResponse* clear_client(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  priv->client_id = kClientIdUnset;

  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}

// Update the IM cursor position.
//
// As text is input by the user, the framework sends two streams of updates
// over the text input channel: updates to the composing rect (cursor rect when
// not in IME composing mode) and updates to the matrix transform from local
// coordinates to Flutter root coordinates. This function is called after each
// of these updates. It transforms the composing rect to GDK window coordinates
// and notifies GTK of the updated cursor position.
static void update_im_cursor_position(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));

  // Skip update if not composing to avoid setting to position 0.
  if (!priv->text_model->composing()) {
    return;
  }

  // Transform the x, y positions of the cursor from local coordinates to
  // Flutter view coordinates.
  gint x = priv->composing_rect.x * priv->editabletext_transform[0][0] +
           priv->composing_rect.y * priv->editabletext_transform[1][0] +
           priv->editabletext_transform[3][0] + priv->composing_rect.width;
  gint y = priv->composing_rect.x * priv->editabletext_transform[0][1] +
           priv->composing_rect.y * priv->editabletext_transform[1][1] +
           priv->editabletext_transform[3][1] + priv->composing_rect.height;

  // Transform from Flutter view coordinates to GTK window coordinates.
  GdkRectangle preedit_rect = {};
  fl_text_input_view_delegate_translate_coordinates(
      priv->view_delegate, x, y, &preedit_rect.x, &preedit_rect.y);

  // Set the cursor location in window coordinates so that GTK can position any
  // system input method windows.
  gtk_im_context_set_cursor_location(priv->im_context, &preedit_rect);
}

// Handles updates to the EditableText size and position from the framework.
//
// On changes to the size or position of the RenderObject underlying the
// EditableText, this update may be triggered. It provides an updated size and
// transform from the local coordinate system of the EditableText to root
// Flutter coordinate system.
static FlMethodResponse* set_editable_size_and_transform(
    FlTextInputPlugin* self,
    FlValue* args) {
  FlValue* transform = fl_value_lookup_string(args, kTransform);
  size_t transform_len = fl_value_get_length(transform);
  g_warn_if_fail(transform_len == 16);

  for (size_t i = 0; i < transform_len; ++i) {
    double val = fl_value_get_float(fl_value_get_list_value(transform, i));
    FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
        fl_text_input_plugin_get_instance_private(self));
    priv->editabletext_transform[i / 4][i % 4] = val;
  }
  update_im_cursor_position(self);

  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}

// Handles updates to the composing rect from the framework.
//
// On changes to the state of the EditableText in the framework, this update
// may be triggered. It provides an updated rect for the composing region in
// local coordinates of the EditableText. In the case where there is no
// composing region, the cursor rect is sent.
static FlMethodResponse* set_marked_text_rect(FlTextInputPlugin* self,
                                              FlValue* args) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  priv->composing_rect.x =
      fl_value_get_float(fl_value_lookup_string(args, "x"));
  priv->composing_rect.y =
      fl_value_get_float(fl_value_lookup_string(args, "y"));
  priv->composing_rect.width =
      fl_value_get_float(fl_value_lookup_string(args, "width"));
  priv->composing_rect.height =
      fl_value_get_float(fl_value_lookup_string(args, "height"));
  update_im_cursor_position(self);

  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}

// Called when a method call is received from Flutter.
static void method_call_cb(FlMethodChannel* channel,
                           FlMethodCall* method_call,
                           gpointer user_data) {
  FlTextInputPlugin* self = FL_TEXT_INPUT_PLUGIN(user_data);

  const gchar* method = fl_method_call_get_name(method_call);
  FlValue* args = fl_method_call_get_args(method_call);

  g_autoptr(FlMethodResponse) response = nullptr;
  if (strcmp(method, kSetClientMethod) == 0) {
    response = set_client(self, args);
  } else if (strcmp(method, kShowMethod) == 0) {
    response = show(self);
  } else if (strcmp(method, kSetEditingStateMethod) == 0) {
    response = set_editing_state(self, args);
  } else if (strcmp(method, kClearClientMethod) == 0) {
    response = clear_client(self);
  } else if (strcmp(method, kHideMethod) == 0) {
    response = hide(self);
  } else if (strcmp(method, kSetEditableSizeAndTransform) == 0) {
    response = set_editable_size_and_transform(self, args);
  } else if (strcmp(method, kSetMarkedTextRect) == 0) {
    response = set_marked_text_rect(self, args);
  } else {
    response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
  }

  g_autoptr(GError) error = nullptr;
  if (!fl_method_call_respond(method_call, response, &error)) {
    g_warning("Failed to send method call response: %s", error->message);
  }
}

// Disposes of an FlTextInputPlugin.
static void fl_text_input_plugin_dispose(GObject* object) {
  FlTextInputPlugin* self = FL_TEXT_INPUT_PLUGIN(object);
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));

  g_clear_object(&priv->channel);
  g_clear_pointer(&priv->input_action, g_free);
  g_clear_object(&priv->im_context);
  if (priv->text_model != nullptr) {
    delete priv->text_model;
    priv->text_model = nullptr;
  }
  if (priv->view_delegate != nullptr) {
    g_object_remove_weak_pointer(
        G_OBJECT(priv->view_delegate),
        reinterpret_cast<gpointer*>(&(priv->view_delegate)));
    priv->view_delegate = nullptr;
  }

  G_OBJECT_CLASS(fl_text_input_plugin_parent_class)->dispose(object);
}

// Implements FlTextInputPlugin::filter_keypress.
static gboolean fl_text_input_plugin_filter_keypress_default(
    FlTextInputPlugin* self,
    FlKeyEvent* event) {
  g_return_val_if_fail(FL_IS_TEXT_INPUT_PLUGIN(self), false);

  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));

  if (priv->client_id == kClientIdUnset) {
    return FALSE;
  }

  if (gtk_im_context_filter_keypress(
          priv->im_context, reinterpret_cast<GdkEventKey*>(event->origin))) {
    return TRUE;
  }

  std::string text_before_change = priv->text_model->GetText();
  flutter::TextRange selection_before_change = priv->text_model->selection();
  std::string text = priv->text_model->GetText();

  // Handle the enter/return key.
  gboolean do_action = FALSE;
  // Handle navigation keys.
  gboolean changed = FALSE;
  if (event->is_press) {
    switch (event->keyval) {
      case GDK_KEY_End:
      case GDK_KEY_KP_End:
        if (event->state & GDK_SHIFT_MASK) {
          changed = priv->text_model->SelectToEnd();
        } else {
          changed = priv->text_model->MoveCursorToEnd();
        }
        break;
      case GDK_KEY_Return:
      case GDK_KEY_KP_Enter:
      case GDK_KEY_ISO_Enter:
        if (priv->input_type == kFlTextInputTypeMultiline &&
            strcmp(priv->input_action, kNewlineInputAction) == 0) {
          priv->text_model->AddCodePoint('\n');
          text = "\n";
          changed = TRUE;
        }
        do_action = TRUE;
        break;
      case GDK_KEY_Home:
      case GDK_KEY_KP_Home:
        if (event->state & GDK_SHIFT_MASK) {
          changed = priv->text_model->SelectToBeginning();
        } else {
          changed = priv->text_model->MoveCursorToBeginning();
        }
        break;
      case GDK_KEY_BackSpace:
      case GDK_KEY_Delete:
      case GDK_KEY_KP_Delete:
      case GDK_KEY_Left:
      case GDK_KEY_KP_Left:
      case GDK_KEY_Right:
      case GDK_KEY_KP_Right:
        // Already handled inside the framework in RenderEditable.
        break;
    }
  }

  if (changed) {
    if (priv->enable_delta_model) {
      flutter::TextEditingDelta delta = flutter::TextEditingDelta(
          text_before_change, selection_before_change, text);
      update_editing_state_with_delta(self, &delta);
    } else {
      update_editing_state(self);
    }
  }
  if (do_action) {
    perform_action(self);
  }

  return changed;
}

// Initializes the FlTextInputPlugin class.
static void fl_text_input_plugin_class_init(FlTextInputPluginClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_text_input_plugin_dispose;
  FL_TEXT_INPUT_PLUGIN_CLASS(klass)->filter_keypress =
      fl_text_input_plugin_filter_keypress_default;
}

// Initializes an instance of the FlTextInputPlugin class.
static void fl_text_input_plugin_init(FlTextInputPlugin* self) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));

  priv->client_id = kClientIdUnset;
  priv->input_type = kFlTextInputTypeText;
  priv->text_model = new flutter::TextInputModel();
}

static void init_im_context(FlTextInputPlugin* self, GtkIMContext* im_context) {
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  priv->im_context = GTK_IM_CONTEXT(g_object_ref(im_context));

  // On Wayland, this call sets up the input method so it can be enabled
  // immediately when required. Without it, on-screen keyboard's don't come up
  // the first time a text field is focused.
  gtk_im_context_focus_out(priv->im_context);

  g_signal_connect_object(priv->im_context, "preedit-start",
                          G_CALLBACK(im_preedit_start_cb), self,
                          G_CONNECT_SWAPPED);
  g_signal_connect_object(priv->im_context, "preedit-end",
                          G_CALLBACK(im_preedit_end_cb), self,
                          G_CONNECT_SWAPPED);
  g_signal_connect_object(priv->im_context, "preedit-changed",
                          G_CALLBACK(im_preedit_changed_cb), self,
                          G_CONNECT_SWAPPED);
  g_signal_connect_object(priv->im_context, "commit", G_CALLBACK(im_commit_cb),
                          self, G_CONNECT_SWAPPED);
  g_signal_connect_object(priv->im_context, "retrieve-surrounding",
                          G_CALLBACK(im_retrieve_surrounding_cb), self,
                          G_CONNECT_SWAPPED);
  g_signal_connect_object(priv->im_context, "delete-surrounding",
                          G_CALLBACK(im_delete_surrounding_cb), self,
                          G_CONNECT_SWAPPED);
}

FlTextInputPlugin* fl_text_input_plugin_new(
    FlBinaryMessenger* messenger,
    GtkIMContext* im_context,
    FlTextInputViewDelegate* view_delegate) {
  g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
  g_return_val_if_fail(GTK_IS_IM_CONTEXT(im_context), nullptr);
  g_return_val_if_fail(FL_IS_TEXT_INPUT_VIEW_DELEGATE(view_delegate), nullptr);

  FlTextInputPlugin* self = FL_TEXT_INPUT_PLUGIN(
      g_object_new(fl_text_input_plugin_get_type(), nullptr));

  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
  FlTextInputPluginPrivate* priv = static_cast<FlTextInputPluginPrivate*>(
      fl_text_input_plugin_get_instance_private(self));
  priv->channel =
      fl_method_channel_new(messenger, kChannelName, FL_METHOD_CODEC(codec));
  fl_method_channel_set_method_call_handler(priv->channel, method_call_cb, self,
                                            nullptr);

  init_im_context(self, im_context);

  priv->view_delegate = view_delegate;
  g_object_add_weak_pointer(
      G_OBJECT(view_delegate),
      reinterpret_cast<gpointer*>(&(priv->view_delegate)));

  return self;
}

// Filters the a keypress given to the plugin through the plugin's
// filter_keypress callback.
gboolean fl_text_input_plugin_filter_keypress(FlTextInputPlugin* self,
                                              FlKeyEvent* event) {
  g_return_val_if_fail(FL_IS_TEXT_INPUT_PLUGIN(self), FALSE);
  if (FL_TEXT_INPUT_PLUGIN_GET_CLASS(self)->filter_keypress) {
    return FL_TEXT_INPUT_PLUGIN_GET_CLASS(self)->filter_keypress(self, event);
  }
  return FALSE;
}
