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

static constexpr int kMicrosecondsPerMillisecond = 1000;

struct _FlScrollingManager {
  GObject parent_instance;

  FlScrollingViewDelegate* view_delegate;

  gdouble last_x;
  gdouble last_y;

  gboolean pan_started;
  gdouble pan_x;
  gdouble pan_y;

  gboolean zoom_started;
  gboolean rotate_started;
  gdouble scale;
  gdouble rotation;
};

G_DEFINE_TYPE(FlScrollingManager, fl_scrolling_manager, G_TYPE_OBJECT);

static void fl_scrolling_manager_dispose(GObject* object) {
  FlScrollingManager* self = FL_SCROLLING_MANAGER(object);

  if (self->view_delegate != nullptr) {
    g_object_remove_weak_pointer(
        object, reinterpret_cast<gpointer*>(&self->view_delegate));
    self->view_delegate = nullptr;
  }

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

static void fl_scrolling_manager_class_init(FlScrollingManagerClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_scrolling_manager_dispose;
}

static void fl_scrolling_manager_init(FlScrollingManager* self) {}

FlScrollingManager* fl_scrolling_manager_new(
    FlScrollingViewDelegate* view_delegate) {
  g_return_val_if_fail(FL_IS_SCROLLING_VIEW_DELEGATE(view_delegate), nullptr);

  FlScrollingManager* self = FL_SCROLLING_MANAGER(
      g_object_new(fl_scrolling_manager_get_type(), nullptr));

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

  self->pan_started = FALSE;
  self->zoom_started = FALSE;
  self->rotate_started = FALSE;

  return self;
}

void fl_scrolling_manager_set_last_mouse_position(FlScrollingManager* self,
                                                  gdouble x,
                                                  gdouble y) {
  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));
  self->last_x = x;
  self->last_y = y;
}

void fl_scrolling_manager_handle_scroll_event(FlScrollingManager* self,
                                              GdkEventScroll* scroll_event,
                                              gint scale_factor) {
  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));

  GdkEvent* event = reinterpret_cast<GdkEvent*>(scroll_event);

  guint event_time = gdk_event_get_time(event);
  gdouble event_x = 0.0, event_y = 0.0;
  gdk_event_get_coords(event, &event_x, &event_y);
  gdouble scroll_delta_x = 0.0, scroll_delta_y = 0.0;
  GdkScrollDirection event_direction = GDK_SCROLL_SMOOTH;
  if (gdk_event_get_scroll_direction(event, &event_direction)) {
    if (event_direction == GDK_SCROLL_UP) {
      scroll_delta_x = 0;
      scroll_delta_y = -1;
    } else if (event_direction == GDK_SCROLL_DOWN) {
      scroll_delta_x = 0;
      scroll_delta_y = 1;
    } else if (event_direction == GDK_SCROLL_LEFT) {
      scroll_delta_x = -1;
      scroll_delta_y = 0;
    } else if (event_direction == GDK_SCROLL_RIGHT) {
      scroll_delta_x = 1;
      scroll_delta_y = 0;
    }
  } else {
    gdk_event_get_scroll_deltas(event, &scroll_delta_x, &scroll_delta_y);
  }

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

  if (gdk_device_get_source(gdk_event_get_source_device(event)) ==
      GDK_SOURCE_TOUCHPAD) {
    scroll_delta_x *= -1;
    scroll_delta_y *= -1;
    if (gdk_event_is_scroll_stop_event(event)) {
      fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
          self->view_delegate, event_time * kMicrosecondsPerMillisecond,
          event_x * scale_factor, event_y * scale_factor, kPanZoomEnd,
          self->pan_x, self->pan_y, 0, 0);
      self->pan_started = FALSE;
    } else {
      if (!self->pan_started) {
        self->pan_x = 0;
        self->pan_y = 0;
        fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
            self->view_delegate, event_time * kMicrosecondsPerMillisecond,
            event_x * scale_factor, event_y * scale_factor, kPanZoomStart, 0, 0,
            0, 0);
        self->pan_started = TRUE;
      }
      self->pan_x += scroll_delta_x;
      self->pan_y += scroll_delta_y;
      fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
          self->view_delegate, event_time * kMicrosecondsPerMillisecond,
          event_x * scale_factor, event_y * scale_factor, kPanZoomUpdate,
          self->pan_x, self->pan_y, 1, 0);
    }
  } else {
    self->last_x = event_x * scale_factor;
    self->last_y = event_y * scale_factor;
    fl_scrolling_view_delegate_send_mouse_pointer_event(
        self->view_delegate,
        FlutterPointerPhase::kMove /* arbitrary value, phase will be ignored as
                                      this is a discrete scroll event */
        ,
        event_time * kMicrosecondsPerMillisecond, event_x * scale_factor,
        event_y * scale_factor, kFlutterPointerDeviceKindMouse, scroll_delta_x,
        scroll_delta_y, 0);
  }
}

void fl_scrolling_manager_handle_rotation_begin(FlScrollingManager* self) {
  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));

  self->rotate_started = TRUE;
  if (!self->zoom_started) {
    self->scale = 1;
    self->rotation = 0;
    fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
        self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
        kPanZoomStart, 0, 0, 0, 0);
  }
}

void fl_scrolling_manager_handle_rotation_update(FlScrollingManager* self,
                                                 gdouble rotation) {
  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));

  self->rotation = rotation;
  fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
      self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
      kPanZoomUpdate, 0, 0, self->scale, self->rotation);
}

void fl_scrolling_manager_handle_rotation_end(FlScrollingManager* self) {
  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));

  self->rotate_started = FALSE;
  if (!self->zoom_started) {
    fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
        self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
        kPanZoomEnd, 0, 0, 0, 0);
  }
}

void fl_scrolling_manager_handle_zoom_begin(FlScrollingManager* self) {
  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));

  self->zoom_started = TRUE;
  if (!self->rotate_started) {
    self->scale = 1;
    self->rotation = 0;
    fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
        self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
        kPanZoomStart, 0, 0, 0, 0);
  }
}

void fl_scrolling_manager_handle_zoom_update(FlScrollingManager* self,
                                             gdouble scale) {
  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));

  self->scale = scale;
  fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
      self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
      kPanZoomUpdate, 0, 0, self->scale, self->rotation);
}

void fl_scrolling_manager_handle_zoom_end(FlScrollingManager* self) {
  g_return_if_fail(FL_IS_SCROLLING_MANAGER(self));

  self->zoom_started = FALSE;
  if (!self->rotate_started) {
    fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
        self->view_delegate, g_get_real_time(), self->last_x, self->last_y,
        kPanZoomEnd, 0, 0, 0, 0);
  }
}
