// 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/public/flutter_linux/fl_view.h"

#include "flutter/shell/platform/linux/fl_view_private.h"

#include <cstring>

#include "flutter/shell/platform/linux/fl_accessibility_plugin.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/fl_key_channel_responder.h"
#include "flutter/shell/platform/linux/fl_key_embedder_responder.h"
#include "flutter/shell/platform/linux/fl_key_event.h"
#include "flutter/shell/platform/linux/fl_keyboard_manager.h"
#include "flutter/shell/platform/linux/fl_mouse_cursor_plugin.h"
#include "flutter/shell/platform/linux/fl_platform_plugin.h"
#include "flutter/shell/platform/linux/fl_plugin_registrar_private.h"
#include "flutter/shell/platform/linux/fl_renderer_gl.h"
#include "flutter/shell/platform/linux/fl_view_accessible.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h"

static constexpr int kMicrosecondsPerMillisecond = 1000;

struct _FlView {
  GtkContainer parent_instance;

  // Project being run.
  FlDartProject* project;

  // Rendering output.
  FlRenderer* renderer;

  // Engine running @project.
  FlEngine* engine;

  // Pointer button state recorded for sending status updates.
  int64_t button_state;

  // Flutter system channel handlers.
  FlAccessibilityPlugin* accessibility_plugin;
  FlKeyboardManager* keyboard_manager;
  FlMouseCursorPlugin* mouse_cursor_plugin;
  FlPlatformPlugin* platform_plugin;

  GList* gl_area_list;
  GList* used_area_list;

  GtkWidget* event_box;

  GList* children_list;
  GList* pending_children_list;

  // Tracks whether mouse pointer is inside the view.
  gboolean pointer_inside;
};

typedef struct _FlViewChild {
  GtkWidget* widget;
  GdkRectangle geometry;
} FlViewChild;

enum { PROP_FLUTTER_PROJECT = 1, PROP_LAST };

static void fl_view_plugin_registry_iface_init(
    FlPluginRegistryInterface* iface);

static gboolean text_input_im_filter_by_gtk(GtkIMContext* im_context,
                                            gpointer gdk_event);

static void redispatch_key_event_by_gtk(gpointer gdk_event);

G_DEFINE_TYPE_WITH_CODE(
    FlView,
    fl_view,
    GTK_TYPE_CONTAINER,
    G_IMPLEMENT_INTERFACE(fl_plugin_registry_get_type(),
                          fl_view_plugin_registry_iface_init))

static void fl_view_update_semantics_node_cb(FlEngine* engine,
                                             const FlutterSemanticsNode* node,
                                             gpointer user_data) {
  FlView* self = FL_VIEW(user_data);

  fl_accessibility_plugin_handle_update_semantics_node(
      self->accessibility_plugin, node);
}

static void fl_view_init_keyboard(FlView* self) {
  FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(self->engine);
  self->keyboard_manager = fl_keyboard_manager_new(
      fl_text_input_plugin_new(messenger, self, text_input_im_filter_by_gtk),
      redispatch_key_event_by_gtk);
  // The embedder responder must be added before the channel responder.
  fl_keyboard_manager_add_responder(
      self->keyboard_manager,
      FL_KEY_RESPONDER(fl_key_embedder_responder_new(self->engine)));
  fl_keyboard_manager_add_responder(
      self->keyboard_manager,
      FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger)));
}

// Invoked by the engine right before the engine is restarted.
//
// This method should reset states to be as if the engine had just been started,
// which usually indicates the user has requested a hot restart (Shift-R in the
// Flutter CLI.)
static void fl_view_on_pre_engine_restart_cb(FlEngine* engine,
                                             gpointer user_data) {
  FlView* self = FL_VIEW(user_data);

  g_clear_object(&self->keyboard_manager);
  fl_view_init_keyboard(self);
}

// Converts a GDK button event into a Flutter event and sends it to the engine.
static gboolean fl_view_send_pointer_button_event(FlView* self,
                                                  GdkEventButton* event) {
  int64_t button;
  switch (event->button) {
    case 1:
      button = kFlutterPointerButtonMousePrimary;
      break;
    case 2:
      button = kFlutterPointerButtonMouseMiddle;
      break;
    case 3:
      button = kFlutterPointerButtonMouseSecondary;
      break;
    default:
      return FALSE;
  }
  int old_button_state = self->button_state;
  FlutterPointerPhase phase = kMove;
  if (event->type == GDK_BUTTON_PRESS) {
    // Drop the event if Flutter already thinks the button is down.
    if ((self->button_state & button) != 0) {
      return FALSE;
    }
    self->button_state ^= button;

    phase = old_button_state == 0 ? kDown : kMove;
  } else if (event->type == GDK_BUTTON_RELEASE) {
    // Drop the event if Flutter already thinks the button is up.
    if ((self->button_state & button) == 0) {
      return FALSE;
    }
    self->button_state ^= button;

    phase = self->button_state == 0 ? kUp : kMove;
  }

  if (self->engine == nullptr) {
    return FALSE;
  }

  gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self));
  fl_engine_send_mouse_pointer_event(
      self->engine, phase, event->time * kMicrosecondsPerMillisecond,
      event->x * scale_factor, event->y * scale_factor, 0, 0,
      self->button_state);

  return TRUE;
}

// Updates the engine with the current window metrics.
static void fl_view_geometry_changed(FlView* self) {
  GtkAllocation allocation;
  gtk_widget_get_allocation(GTK_WIDGET(self), &allocation);
  gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self));
  fl_engine_send_window_metrics_event(
      self->engine, allocation.width * scale_factor,
      allocation.height * scale_factor, scale_factor);

  fl_renderer_wait_for_frame(self->renderer, allocation.width * scale_factor,
                             allocation.height * scale_factor);
}

// Implements FlPluginRegistry::get_registrar_for_plugin.
static FlPluginRegistrar* fl_view_get_registrar_for_plugin(
    FlPluginRegistry* registry,
    const gchar* name) {
  FlView* self = FL_VIEW(registry);

  return fl_plugin_registrar_new(self,
                                 fl_engine_get_binary_messenger(self->engine),
                                 fl_engine_get_texture_registrar(self->engine));
}

static void fl_view_plugin_registry_iface_init(
    FlPluginRegistryInterface* iface) {
  iface->get_registrar_for_plugin = fl_view_get_registrar_for_plugin;
}

static gboolean event_box_button_release_event(GtkWidget* widget,
                                               GdkEventButton* event,
                                               FlView* view);

static gboolean event_box_button_press_event(GtkWidget* widget,
                                             GdkEventButton* event,
                                             FlView* view);

static gboolean event_box_scroll_event(GtkWidget* widget,
                                       GdkEventScroll* event,
                                       FlView* view);

static gboolean event_box_motion_notify_event(GtkWidget* widget,
                                              GdkEventMotion* event,
                                              FlView* view);

static gboolean event_box_enter_notify_event(GtkWidget* widget,
                                             GdkEventCrossing* event,
                                             FlView* view);

static gboolean event_box_leave_notify_event(GtkWidget* widget,
                                             GdkEventCrossing* event,
                                             FlView* view);

static void fl_view_constructed(GObject* object) {
  FlView* self = FL_VIEW(object);

  self->renderer = FL_RENDERER(fl_renderer_gl_new());
  self->engine = fl_engine_new(self->project, self->renderer);
  fl_engine_set_update_semantics_node_handler(
      self->engine, fl_view_update_semantics_node_cb, self, nullptr);
  fl_engine_set_on_pre_engine_restart_handler(
      self->engine, fl_view_on_pre_engine_restart_cb, self, nullptr);

  // Create system channel handlers.
  FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(self->engine);
  self->accessibility_plugin = fl_accessibility_plugin_new(self);
  fl_view_init_keyboard(self);
  self->mouse_cursor_plugin = fl_mouse_cursor_plugin_new(messenger, self);
  self->platform_plugin = fl_platform_plugin_new(messenger);

  self->event_box = gtk_event_box_new();
  gtk_widget_set_parent(self->event_box, GTK_WIDGET(self));
  gtk_widget_show(self->event_box);
  gtk_widget_add_events(self->event_box,
                        GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK |
                            GDK_BUTTON_RELEASE_MASK | GDK_SCROLL_MASK |
                            GDK_SMOOTH_SCROLL_MASK);

  g_signal_connect(self->event_box, "button-press-event",
                   G_CALLBACK(event_box_button_press_event), self);
  g_signal_connect(self->event_box, "button-release-event",
                   G_CALLBACK(event_box_button_release_event), self);
  g_signal_connect(self->event_box, "scroll-event",
                   G_CALLBACK(event_box_scroll_event), self);
  g_signal_connect(self->event_box, "motion-notify-event",
                   G_CALLBACK(event_box_motion_notify_event), self);
  g_signal_connect(self->event_box, "enter-notify-event",
                   G_CALLBACK(event_box_enter_notify_event), self);
  g_signal_connect(self->event_box, "leave-notify-event",
                   G_CALLBACK(event_box_leave_notify_event), self);
}

static void fl_view_set_property(GObject* object,
                                 guint prop_id,
                                 const GValue* value,
                                 GParamSpec* pspec) {
  FlView* self = FL_VIEW(object);

  switch (prop_id) {
    case PROP_FLUTTER_PROJECT:
      g_set_object(&self->project,
                   static_cast<FlDartProject*>(g_value_get_object(value)));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
      break;
  }
}

static void fl_view_get_property(GObject* object,
                                 guint prop_id,
                                 GValue* value,
                                 GParamSpec* pspec) {
  FlView* self = FL_VIEW(object);

  switch (prop_id) {
    case PROP_FLUTTER_PROJECT:
      g_value_set_object(value, self->project);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
      break;
  }
}

static void fl_view_notify(GObject* object, GParamSpec* pspec) {
  FlView* self = FL_VIEW(object);

  if (strcmp(pspec->name, "scale-factor") == 0) {
    fl_view_geometry_changed(self);
  }

  if (G_OBJECT_CLASS(fl_view_parent_class)->notify != nullptr) {
    G_OBJECT_CLASS(fl_view_parent_class)->notify(object, pspec);
  }
}

static void fl_view_dispose(GObject* object) {
  FlView* self = FL_VIEW(object);

  if (self->engine != nullptr) {
    fl_engine_set_update_semantics_node_handler(self->engine, nullptr, nullptr,
                                                nullptr);
    fl_engine_set_on_pre_engine_restart_handler(self->engine, nullptr, nullptr,
                                                nullptr);
  }

  g_clear_object(&self->project);
  g_clear_object(&self->renderer);
  g_clear_object(&self->engine);
  g_clear_object(&self->accessibility_plugin);
  g_clear_object(&self->keyboard_manager);
  g_clear_object(&self->mouse_cursor_plugin);
  g_clear_object(&self->platform_plugin);
  g_list_free_full(self->gl_area_list, g_object_unref);
  self->gl_area_list = nullptr;

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

// Implements GtkWidget::realize.
static void fl_view_realize(GtkWidget* widget) {
  FlView* self = FL_VIEW(widget);
  g_autoptr(GError) error = nullptr;

  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);

  gtk_widget_set_realized(widget, TRUE);

  GdkWindowAttr attributes;
  attributes.window_type = GDK_WINDOW_CHILD;
  attributes.x = allocation.x;
  attributes.y = allocation.y;
  attributes.width = allocation.width;
  attributes.height = allocation.height;
  attributes.wclass = GDK_INPUT_OUTPUT;
  attributes.visual = gtk_widget_get_visual(widget);
  attributes.event_mask =
      gtk_widget_get_events(widget) | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK;
  gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
  GdkWindow* window = gdk_window_new(gtk_widget_get_parent_window(widget),
                                     &attributes, attributes_mask);
  gtk_widget_set_window(widget, window);
  gtk_widget_register_window(widget, window);

  if (!fl_renderer_start(self->renderer, self, &error)) {
    g_warning("Failed to start Flutter renderer: %s", error->message);
    return;
  }

  if (!fl_engine_start(self->engine, &error)) {
    g_warning("Failed to start Flutter engine: %s", error->message);
    return;
  }
}

static void fl_view_get_preferred_width(GtkWidget* widget,
                                        gint* minimum,
                                        gint* natural) {
  FlView* self = FL_VIEW(widget);
  gint child_min, child_nat;

  *minimum = 0;
  *natural = 0;

  for (GList* iterator = self->children_list; iterator;
       iterator = iterator->next) {
    FlViewChild* child = reinterpret_cast<FlViewChild*>(iterator->data);

    if (!gtk_widget_get_visible(child->widget)) {
      continue;
    }

    gtk_widget_get_preferred_width(child->widget, &child_min, &child_nat);

    *minimum = MAX(*minimum, child->geometry.x + child_min);
    *natural = MAX(*natural, child->geometry.x + child_nat);
  }
}

static void fl_view_get_preferred_height(GtkWidget* widget,
                                         gint* minimum,
                                         gint* natural) {
  FlView* self = FL_VIEW(widget);
  gint child_min, child_nat;

  *minimum = 0;
  *natural = 0;

  for (GList* iterator = self->children_list; iterator;
       iterator = iterator->next) {
    FlViewChild* child = reinterpret_cast<FlViewChild*>(iterator->data);

    if (!gtk_widget_get_visible(child->widget)) {
      continue;
    }

    gtk_widget_get_preferred_height(child->widget, &child_min, &child_nat);

    *minimum = MAX(*minimum, child->geometry.y + child_min);
    *natural = MAX(*natural, child->geometry.y + child_nat);
  }
}

// Implements GtkWidget::size-allocate.
static void fl_view_size_allocate(GtkWidget* widget,
                                  GtkAllocation* allocation) {
  FlView* self = FL_VIEW(widget);

  gtk_widget_set_allocation(widget, allocation);

  if (gtk_widget_get_has_window(widget)) {
    if (gtk_widget_get_realized(widget)) {
      gdk_window_move_resize(gtk_widget_get_window(widget), allocation->x,
                             allocation->y, allocation->width,
                             allocation->height);
    }
  }

  for (GList* iterator = self->children_list; iterator;
       iterator = iterator->next) {
    FlViewChild* child = reinterpret_cast<FlViewChild*>(iterator->data);
    if (!gtk_widget_get_visible(child->widget)) {
      continue;
    }

    GtkAllocation child_allocation = child->geometry;
    GtkRequisition child_requisition;
    gtk_widget_get_preferred_size(child->widget, &child_requisition, NULL);

    if (!gtk_widget_get_has_window(widget)) {
      child_allocation.x += allocation->x;
      child_allocation.y += allocation->y;
    }

    if (child_allocation.width == 0 && child_allocation.height == 0) {
      child_allocation.width = allocation->width;
      child_allocation.height = allocation->height;
    }

    gtk_widget_size_allocate(child->widget, &child_allocation);
  }

  GtkAllocation event_box_allocation = {
      .x = 0,
      .y = 0,
      .width = allocation->width,
      .height = allocation->height,
  };
  if (!gtk_widget_get_has_window(self->event_box)) {
    event_box_allocation.x += allocation->x;
    event_box_allocation.y += allocation->y;
  }
  gtk_widget_size_allocate(self->event_box, &event_box_allocation);

  fl_view_geometry_changed(self);
}

struct _ReorderData {
  GdkWindow* parent_window;
  GdkWindow* last_window;
};

static void fl_view_reorder_forall(GtkWidget* widget, gpointer user_data) {
  _ReorderData* data = reinterpret_cast<_ReorderData*>(user_data);
  GdkWindow* window = gtk_widget_get_window(widget);
  if (window && window != data->parent_window) {
    if (data->last_window) {
      gdk_window_restack(window, data->last_window, TRUE);
    }
    data->last_window = window;
  }
}

static gboolean event_box_button_press_event(GtkWidget* widget,
                                             GdkEventButton* event,
                                             FlView* view) {
  // Flutter doesn't handle double and triple click events.
  if (event->type == GDK_DOUBLE_BUTTON_PRESS ||
      event->type == GDK_TRIPLE_BUTTON_PRESS) {
    return FALSE;
  }

  if (!gtk_widget_has_focus(GTK_WIDGET(view))) {
    gtk_widget_grab_focus(GTK_WIDGET(view));
  }

  return fl_view_send_pointer_button_event(view, event);
}

static gboolean event_box_button_release_event(GtkWidget* widget,
                                               GdkEventButton* event,
                                               FlView* view) {
  return fl_view_send_pointer_button_event(view, event);
}

static gboolean event_box_scroll_event(GtkWidget* widget,
                                       GdkEventScroll* event,
                                       FlView* view) {
  // TODO(robert-ancell): Update to use GtkEventControllerScroll when we can
  // depend on GTK 3.24.

  gdouble scroll_delta_x = 0.0, scroll_delta_y = 0.0;
  if (event->direction == GDK_SCROLL_SMOOTH) {
    scroll_delta_x = event->delta_x;
    scroll_delta_y = event->delta_y;
  } else if (event->direction == GDK_SCROLL_UP) {
    scroll_delta_y = -1;
  } else if (event->direction == GDK_SCROLL_DOWN) {
    scroll_delta_y = 1;
  } else if (event->direction == GDK_SCROLL_LEFT) {
    scroll_delta_x = -1;
  } else if (event->direction == GDK_SCROLL_RIGHT) {
    scroll_delta_x = 1;
  }

  // The multiplier is taken from the Chromium source
  // (ui/events/x/events_x_utils.cc).
  const int kScrollOffsetMultiplier = 53;
  scroll_delta_x *= kScrollOffsetMultiplier;
  scroll_delta_y *= kScrollOffsetMultiplier;

  gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(view));
  fl_engine_send_mouse_pointer_event(
      view->engine, view->button_state != 0 ? kMove : kHover,
      event->time * kMicrosecondsPerMillisecond, event->x * scale_factor,
      event->y * scale_factor, scroll_delta_x, scroll_delta_y,
      view->button_state);

  return TRUE;
}

static void check_pointer_inside(FlView* view, GdkEvent* event) {
  if (!view->pointer_inside) {
    view->pointer_inside = TRUE;

    gdouble x, y;
    if (gdk_event_get_coords(event, &x, &y)) {
      gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(view));

      fl_engine_send_mouse_pointer_event(
          view->engine, kAdd,
          gdk_event_get_time(event) * kMicrosecondsPerMillisecond,
          x * scale_factor, y * scale_factor, 0, 0, view->button_state);
    }
  }
}

static gboolean event_box_motion_notify_event(GtkWidget* widget,
                                              GdkEventMotion* event,
                                              FlView* view) {
  if (view->engine == nullptr) {
    return FALSE;
  }

  check_pointer_inside(view, reinterpret_cast<GdkEvent*>(event));

  gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(view));
  fl_engine_send_mouse_pointer_event(
      view->engine, view->button_state != 0 ? kMove : kHover,
      event->time * kMicrosecondsPerMillisecond, event->x * scale_factor,
      event->y * scale_factor, 0, 0, view->button_state);

  return TRUE;
}

static gboolean event_box_enter_notify_event(GtkWidget* widget,
                                             GdkEventCrossing* event,
                                             FlView* view) {
  if (view->engine == nullptr) {
    return FALSE;
  }

  check_pointer_inside(view, reinterpret_cast<GdkEvent*>(event));

  return TRUE;
}

static gboolean event_box_leave_notify_event(GtkWidget* widget,
                                             GdkEventCrossing* event,
                                             FlView* view) {
  if (view->engine == nullptr) {
    return FALSE;
  }

  // Don't remove pointer while button is down; In case of dragging outside of
  // window with mouse grab active Gtk will send another leave notify on
  // release.
  if (view->pointer_inside && view->button_state == 0) {
    gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(view));
    fl_engine_send_mouse_pointer_event(
        view->engine, kRemove, event->time * kMicrosecondsPerMillisecond,
        event->x * scale_factor, event->y * scale_factor, 0, 0,
        view->button_state);
    view->pointer_inside = FALSE;
  }

  return TRUE;
}

// Implements GtkWidget::key_press_event.
static gboolean fl_view_key_press_event(GtkWidget* widget, GdkEventKey* event) {
  FlView* self = FL_VIEW(widget);

  return fl_keyboard_manager_handle_event(
      self->keyboard_manager, fl_key_event_new_from_gdk_event(gdk_event_copy(
                                  reinterpret_cast<GdkEvent*>(event))));
}

// Implements GtkWidget::key_release_event.
static gboolean fl_view_key_release_event(GtkWidget* widget,
                                          GdkEventKey* event) {
  FlView* self = FL_VIEW(widget);
  return fl_keyboard_manager_handle_event(
      self->keyboard_manager, fl_key_event_new_from_gdk_event(gdk_event_copy(
                                  reinterpret_cast<GdkEvent*>(event))));
}

static void fl_view_put(FlView* self,
                        GtkWidget* widget,
                        GdkRectangle* geometry) {
  FlViewChild* child = g_new(FlViewChild, 1);
  child->widget = widget;
  child->geometry = *geometry;

  gtk_widget_set_parent(widget, GTK_WIDGET(self));
  self->children_list = g_list_append(self->children_list, child);
}

static void fl_view_add(GtkContainer* container, GtkWidget* widget) {
  GdkRectangle geometry = {
      .x = 0,
      .y = 0,
      .width = 0,
      .height = 0,
  };
  fl_view_put(FL_VIEW(container), widget, &geometry);
}

static void fl_view_remove(GtkContainer* container, GtkWidget* widget) {
  FlView* self = FL_VIEW(container);
  for (GList* iterator = self->children_list; iterator;
       iterator = iterator->next) {
    FlViewChild* child = reinterpret_cast<FlViewChild*>(iterator->data);
    if (child->widget == widget) {
      g_object_ref(widget);
      gtk_widget_unparent(widget);
      self->children_list = g_list_remove_link(self->children_list, iterator);
      g_list_free(iterator);
      g_free(child);

      break;
    }
  }

  if (widget == GTK_WIDGET(self->event_box)) {
    g_clear_object(&self->event_box);
  }
}

static void fl_view_forall(GtkContainer* container,
                           gboolean include_internals,
                           GtkCallback callback,
                           gpointer callback_data) {
  FlView* self = FL_VIEW(container);
  for (GList* iterator = self->children_list; iterator;
       iterator = iterator->next) {
    FlViewChild* child = reinterpret_cast<FlViewChild*>(iterator->data);
    (*callback)(child->widget, callback_data);
  }

  if (include_internals) {
    (*callback)(self->event_box, callback_data);
  }
}

static GType fl_view_child_type(GtkContainer* container) {
  return GTK_TYPE_WIDGET;
}

static void fl_view_set_child_property(GtkContainer* container,
                                       GtkWidget* child,
                                       guint property_id,
                                       const GValue* value,
                                       GParamSpec* pspec) {}

static void fl_view_get_child_property(GtkContainer* container,
                                       GtkWidget* child,
                                       guint property_id,
                                       GValue* value,
                                       GParamSpec* pspec) {}

static void fl_view_class_init(FlViewClass* klass) {
  GObjectClass* object_class = G_OBJECT_CLASS(klass);
  object_class->constructed = fl_view_constructed;
  object_class->set_property = fl_view_set_property;
  object_class->get_property = fl_view_get_property;
  object_class->notify = fl_view_notify;
  object_class->dispose = fl_view_dispose;

  GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
  widget_class->realize = fl_view_realize;
  widget_class->get_preferred_width = fl_view_get_preferred_width;
  widget_class->get_preferred_height = fl_view_get_preferred_height;
  widget_class->size_allocate = fl_view_size_allocate;
  widget_class->key_press_event = fl_view_key_press_event;
  widget_class->key_release_event = fl_view_key_release_event;

  GtkContainerClass* container_class = GTK_CONTAINER_CLASS(klass);
  container_class->add = fl_view_add;
  container_class->remove = fl_view_remove;
  container_class->forall = fl_view_forall;
  container_class->child_type = fl_view_child_type;
  container_class->set_child_property = fl_view_set_child_property;
  container_class->get_child_property = fl_view_get_child_property;

  g_object_class_install_property(
      G_OBJECT_CLASS(klass), PROP_FLUTTER_PROJECT,
      g_param_spec_object(
          "flutter-project", "flutter-project", "Flutter project in use",
          fl_dart_project_get_type(),
          static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                                   G_PARAM_STATIC_STRINGS)));

  gtk_widget_class_set_accessible_type(GTK_WIDGET_CLASS(klass),
                                       fl_view_accessible_get_type());
}

static void fl_view_init(FlView* self) {
  gtk_widget_set_can_focus(GTK_WIDGET(self), TRUE);
}

G_MODULE_EXPORT FlView* fl_view_new(FlDartProject* project) {
  return static_cast<FlView*>(
      g_object_new(fl_view_get_type(), "flutter-project", project, nullptr));
}

G_MODULE_EXPORT FlEngine* fl_view_get_engine(FlView* view) {
  g_return_val_if_fail(FL_IS_VIEW(view), nullptr);
  return view->engine;
}

void fl_view_begin_frame(FlView* view) {
  g_return_if_fail(FL_IS_VIEW(view));
  FlView* self = FL_VIEW(view);

  self->used_area_list = self->gl_area_list;
  g_list_free_full(self->pending_children_list, g_free);
  self->pending_children_list = nullptr;
}

static void fl_view_add_pending_child(FlView* self,
                                      GtkWidget* widget,
                                      GdkRectangle* geometry) {
  FlViewChild* child = g_new(FlViewChild, 1);
  child->widget = widget;
  if (geometry) {
    child->geometry = *geometry;
  } else {
    child->geometry = {0, 0, 0, 0};
  }

  self->pending_children_list =
      g_list_append(self->pending_children_list, child);
}

void fl_view_add_gl_area(FlView* view,
                         GdkGLContext* context,
                         FlBackingStoreProvider* texture) {
  g_return_if_fail(FL_IS_VIEW(view));

  FlGLArea* area;
  if (view->used_area_list) {
    area = reinterpret_cast<FlGLArea*>(view->used_area_list->data);
    view->used_area_list = view->used_area_list->next;
  } else {
    area = FL_GL_AREA(fl_gl_area_new(context));
    view->gl_area_list = g_list_append(view->gl_area_list, area);
  }

  gtk_widget_show(GTK_WIDGET(area));
  fl_view_add_pending_child(view, GTK_WIDGET(area), nullptr);
  fl_gl_area_queue_render(area, texture);
}

void fl_view_add_widget(FlView* view,
                        GtkWidget* widget,
                        GdkRectangle* geometry) {
  gtk_widget_show(widget);
  fl_view_add_pending_child(view, widget, geometry);
}

GList* find_child(GList* list, GtkWidget* widget) {
  for (GList* i = list; i; i = i->next) {
    FlViewChild* child = reinterpret_cast<FlViewChild*>(i->data);
    if (child && child->widget == widget) {
      return i;
    }
  }
  return nullptr;
}

void fl_view_end_frame(FlView* view) {
  for (GList* pending_child = view->pending_children_list; pending_child;
       pending_child = pending_child->next) {
    FlViewChild* pending_view_child =
        reinterpret_cast<FlViewChild*>(pending_child->data);
    GList* child = find_child(view->children_list, pending_view_child->widget);

    if (child) {
      // existing child
      g_free(child->data);
      child->data = nullptr;
    } else {
      // newly added child
      gtk_widget_set_parent(pending_view_child->widget, GTK_WIDGET(view));
    }
  }

  for (GList* child = view->children_list; child; child = child->next) {
    FlViewChild* view_child = reinterpret_cast<FlViewChild*>(child->data);
    if (view_child) {
      // removed child
      g_object_ref(view_child->widget);
      gtk_widget_unparent(view_child->widget);
      g_free(view_child);
      child->data = nullptr;
    }
  }

  g_list_free(view->children_list);
  view->children_list = view->pending_children_list;
  view->pending_children_list = nullptr;

  struct _ReorderData data = {
      .parent_window = gtk_widget_get_window(GTK_WIDGET(view)),
      .last_window = nullptr,
  };

  gtk_container_forall(GTK_CONTAINER(view), fl_view_reorder_forall, &data);

  gtk_widget_queue_draw(GTK_WIDGET(view));
}

static void redispatch_key_event_by_gtk(gpointer raw_event) {
  GdkEvent* gdk_event = reinterpret_cast<GdkEvent*>(raw_event);
  GdkEventType type = gdk_event->type;
  g_return_if_fail(type == GDK_KEY_PRESS || type == GDK_KEY_RELEASE);
  gdk_event_put(gdk_event);
}

static gboolean text_input_im_filter_by_gtk(GtkIMContext* im_context,
                                            gpointer gdk_event) {
  GdkEventKey* event = reinterpret_cast<GdkEventKey*>(gdk_event);
  GdkEventType type = event->type;
  g_return_val_if_fail(type == GDK_KEY_PRESS || type == GDK_KEY_RELEASE, false);
  return gtk_im_context_filter_keypress(im_context, event);
}
