// Copyright 2018 The Chromium 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 "ui/ozone/platform/wayland/wayland_touch.h"

#include <sys/mman.h>
#include <wayland-client.h>

#include "base/files/scoped_file.h"
#include "base/memory/ptr_util.h"
#include "ui/base/ui_features.h"
#include "ui/events/event.h"
#include "ui/ozone/platform/wayland/wayland_connection.h"
#include "ui/ozone/platform/wayland/wayland_window.h"

namespace ui {

WaylandTouch::TouchPoint::TouchPoint() = default;

WaylandTouch::TouchPoint::TouchPoint(gfx::Point location,
                                     wl_surface* current_surface)
    : surface(current_surface), last_known_location(location) {}

WaylandTouch::TouchPoint::~TouchPoint() = default;

//-----------------------------------------------------------------------------

WaylandTouch::WaylandTouch(wl_touch* touch,
                           const EventDispatchCallback& callback)
    : obj_(touch), callback_(callback) {
  static const wl_touch_listener listener = {
      &WaylandTouch::Down,  &WaylandTouch::Up,     &WaylandTouch::Motion,
      &WaylandTouch::Frame, &WaylandTouch::Cancel,
  };

  wl_touch_add_listener(obj_.get(), &listener, this);
}

WaylandTouch::~WaylandTouch() {
  DCHECK(current_points_.empty());
}

void WaylandTouch::RemoveTouchPoints(const WaylandWindow* window) {
  base::EraseIf(current_points_,
                [window](const TouchPoints::value_type& point) {
                  return point.second.surface == window->surface();
                });
}

void WaylandTouch::MaybeUnsetFocus(const WaylandTouch::TouchPoints& points,
                                   int32_t id,
                                   wl_surface* surface) {
  for (const auto& point : points) {
    // Return early on the first other point having this surface.
    if (surface == point.second.surface && id != point.first)
      return;
  }
  DCHECK(surface);
  WaylandWindow::FromSurface(surface)->set_touch_focus(false);
}

void WaylandTouch::Down(void* data,
                        wl_touch* obj,
                        uint32_t serial,
                        uint32_t time,
                        struct wl_surface* surface,
                        int32_t id,
                        wl_fixed_t x,
                        wl_fixed_t y) {
  if (!surface)
    return;
  WaylandTouch* touch = static_cast<WaylandTouch*>(data);
  DCHECK(touch);
  touch->connection_->set_serial(serial);
  WaylandWindow::FromSurface(surface)->set_touch_focus(true);

  // Make sure this touch point wasn't present before.
  if (touch->current_points_.find(id) != touch->current_points_.end()) {
    LOG(WARNING) << "Touch down fired with wrong id";
    return;
  }

  EventType type = ET_TOUCH_PRESSED;
  gfx::Point location(wl_fixed_to_double(x), wl_fixed_to_double(y));
  base::TimeTicks time_stamp =
      base::TimeTicks() + base::TimeDelta::FromMilliseconds(time);
  PointerDetails pointer_details(EventPointerType::POINTER_TYPE_TOUCH, id);
  TouchEvent event(type, location, time_stamp, pointer_details);
  touch->callback_.Run(&event);

  touch->current_points_[id] = TouchPoint(location, surface);
}

void WaylandTouch::Up(void* data,
                      wl_touch* obj,
                      uint32_t serial,
                      uint32_t time,
                      int32_t id) {
  WaylandTouch* touch = static_cast<WaylandTouch*>(data);
  DCHECK(touch);
  const auto iterator = touch->current_points_.find(id);

  // Make sure this touch point was present before.
  if (iterator == touch->current_points_.end()) {
    LOG(WARNING) << "Touch up fired with no matching touch down";
    return;
  }

  EventType type = ET_TOUCH_RELEASED;
  base::TimeTicks time_stamp =
      base::TimeTicks() + base::TimeDelta::FromMilliseconds(time);
  PointerDetails pointer_details(EventPointerType::POINTER_TYPE_TOUCH, id);
  TouchEvent event(type, touch->current_points_[id].last_known_location,
                   time_stamp, pointer_details);
  touch->callback_.Run(&event);

  touch->MaybeUnsetFocus(touch->current_points_, id,
                         touch->current_points_[id].surface);
  touch->current_points_.erase(iterator);
}

void WaylandTouch::Motion(void* data,
                          wl_touch* obj,
                          uint32_t time,
                          int32_t id,
                          wl_fixed_t x,
                          wl_fixed_t y) {
  WaylandTouch* touch = static_cast<WaylandTouch*>(data);
  DCHECK(touch);

  // Make sure this touch point wasn't present before.
  if (touch->current_points_.find(id) == touch->current_points_.end()) {
    LOG(WARNING) << "Touch event fired with wrong id";
    return;
  }

  EventType type = ET_TOUCH_MOVED;
  gfx::Point location(wl_fixed_to_double(x), wl_fixed_to_double(y));
  base::TimeTicks time_stamp =
      base::TimeTicks() + base::TimeDelta::FromMilliseconds(time);
  PointerDetails pointer_details(EventPointerType::POINTER_TYPE_TOUCH, id);
  TouchEvent event(type, location, time_stamp, pointer_details);
  touch->callback_.Run(&event);
  touch->current_points_[id].last_known_location = location;
}

void WaylandTouch::Frame(void* data, wl_touch* obj) {}

void WaylandTouch::Cancel(void* data, wl_touch* obj) {
  WaylandTouch* touch = static_cast<WaylandTouch*>(data);
  DCHECK(touch);
  for (auto& point : touch->current_points_) {
    int32_t id = point.first;

    EventType type = ET_TOUCH_CANCELLED;
    base::TimeTicks time_stamp = base::TimeTicks::Now();
    PointerDetails pointer_details(EventPointerType::POINTER_TYPE_TOUCH, id);
    TouchEvent event(type, gfx::Point(), time_stamp, pointer_details);
    touch->callback_.Run(&event);

    WaylandWindow::FromSurface(point.second.surface)->set_touch_focus(false);
  }
  touch->current_points_.clear();
}

}  // namespace ui
