// 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);

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) {}

static void fl_scrolling_manager_dispose(GObject* object) {
  G_OBJECT_CLASS(fl_scrolling_manager_parent_class)->dispose(object);
}

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) {
  self->last_x = x;
  self->last_y = y;
}

void fl_scrolling_manager_handle_scroll_event(FlScrollingManager* self,
                                              GdkEventScroll* scroll_event,
                                              gint scale_factor) {
  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, scroll_delta_x, scroll_delta_y, 0);
  }
}

void fl_scrolling_manager_handle_rotation_begin(FlScrollingManager* 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) {
  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) {
  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) {
  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) {
  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) {
  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);
  }
}
