/*
 * Copyright 2017-2018 Collabora, Ltd.
 * Copyright 2017-2018 General Electric Company
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "config.h"

#include <string.h>
#include <wayland-server.h>

#include "shared/helpers.h"
#include "shared/string-helpers.h"
#include "shared/zalloc.h"
#include "shared/timespec-util.h"
#include "compositor.h"

#include "weston-touch-calibration-server-protocol.h"

struct weston_touch_calibrator {
	struct wl_resource *resource;

	struct weston_compositor *compositor;

	struct weston_surface *surface;
	struct wl_listener surface_destroy_listener;
	struct wl_listener surface_commit_listener;

	struct weston_touch_device *device;
	struct wl_listener device_destroy_listener;

	struct weston_output *output;
	struct wl_listener output_destroy_listener;

	struct weston_view *view;

	/** The calibration procedure has been cancelled. */
	bool calibration_cancelled;

	/** The current touch sequence has been cancelled. */
	bool touch_cancelled;
};

static struct weston_touch_calibrator *
calibrator_from_device(struct weston_touch_device *device)
{
	return device->aggregate->seat->compositor->touch_calibrator;
}

static uint32_t
wire_uint_from_double(double c)
{
	assert(c >= 0.0);
	assert(c <= 1.0);

	return round(c * 0xffffffff);
}

static bool
normalized_is_valid(const struct weston_point2d_device_normalized *p)
{
	return p->x >= 0.0 && p->x <= 1.0 &&
	       p->y >= 0.0 && p->y <= 1.0;
}

WL_EXPORT void
notify_touch_calibrator(struct weston_touch_device *device,
			const struct timespec *time, int32_t slot,
			const struct weston_point2d_device_normalized *norm,
			int touch_type)
{
	struct weston_touch_calibrator *calibrator;
	struct wl_resource *res;
	uint32_t msecs;
	uint32_t x = 0;
	uint32_t y = 0;

	calibrator = calibrator_from_device(device);
	if (!calibrator)
		return;

	res = calibrator->resource;

	/* Ignore any touch events coming from another device */
	if (device != calibrator->device) {
		if (touch_type == WL_TOUCH_DOWN)
			weston_touch_calibrator_send_invalid_touch(res);
		return;
	}

	/* Ignore all events if we have sent 'cancel' event until all
	 * touches (on the seat) are up.
	 */
	if (calibrator->touch_cancelled) {
		if (calibrator->device->aggregate->num_tp == 0) {
			assert(touch_type == WL_TOUCH_UP);
			calibrator->touch_cancelled = false;
		}
		return;
	}

	msecs = timespec_to_msec(time);
	if (touch_type != WL_TOUCH_UP) {
		if (normalized_is_valid(norm)) {
			x = wire_uint_from_double(norm->x);
			y = wire_uint_from_double(norm->y);
		} else {
			/* Coordinates are out of bounds */
			if (touch_type == WL_TOUCH_MOTION) {
				weston_touch_calibrator_send_cancel(res);
				calibrator->touch_cancelled = true;
			}
			weston_touch_calibrator_send_invalid_touch(res);
			return;
		}
	}

	switch (touch_type) {
	case WL_TOUCH_UP:
		weston_touch_calibrator_send_up(res, msecs, slot);
		break;
	case WL_TOUCH_DOWN:
		weston_touch_calibrator_send_down(res, msecs, slot, x, y);
		break;
	case WL_TOUCH_MOTION:
		weston_touch_calibrator_send_motion(res, msecs, slot, x, y);
		break;
	default:
		return;
	}
}

WL_EXPORT void
notify_touch_calibrator_frame(struct weston_touch_device *device)
{
	struct weston_touch_calibrator *calibrator;

	calibrator = calibrator_from_device(device);
	if (!calibrator)
		return;

	weston_touch_calibrator_send_frame(calibrator->resource);
}

WL_EXPORT void
notify_touch_calibrator_cancel(struct weston_touch_device *device)
{
	struct weston_touch_calibrator *calibrator;

	calibrator = calibrator_from_device(device);
	if (!calibrator)
		return;

	weston_touch_calibrator_send_cancel(calibrator->resource);
}

static void
map_calibrator(struct weston_touch_calibrator *calibrator)
{
	struct weston_compositor *c = calibrator->compositor;
	struct weston_touch_device *device = calibrator->device;
	static const struct weston_touch_device_matrix identity = {
		.m = { 1, 0, 0, 0, 1, 0}
	};

	assert(!calibrator->view);
	assert(calibrator->output);
	assert(calibrator->surface);
	assert(calibrator->surface->resource);

	calibrator->view = weston_view_create(calibrator->surface);
	if (!calibrator->view) {
		wl_resource_post_no_memory(calibrator->surface->resource);
		return;
	}

	weston_layer_entry_insert(&c->calibrator_layer.view_list,
				  &calibrator->view->layer_link);

	weston_view_set_position(calibrator->view,
				 calibrator->output->x,
				 calibrator->output->y);
	calibrator->view->output = calibrator->surface->output;
	calibrator->view->is_mapped = true;

	calibrator->surface->output = calibrator->output;
	calibrator->surface->is_mapped = true;

	weston_output_schedule_repaint(calibrator->output);

	device->ops->get_calibration(device, &device->saved_calibration);
	device->ops->set_calibration(device, &identity);
}

static void
unmap_calibrator(struct weston_touch_calibrator *calibrator)
{
	struct weston_touch_device *device = calibrator->device;

	wl_list_remove(&calibrator->surface_commit_listener.link);
	wl_list_init(&calibrator->surface_commit_listener.link);

	if (!calibrator->view)
		return;

	weston_view_destroy(calibrator->view);
	calibrator->view = NULL;
	weston_surface_unmap(calibrator->surface);

	/* Reload saved calibration */
	if (device)
		device->ops->set_calibration(device,
					     &device->saved_calibration);
}

void
touch_calibrator_mode_changed(struct weston_compositor *compositor)
{
	struct weston_touch_calibrator *calibrator;

	calibrator = compositor->touch_calibrator;
	if (!calibrator)
		return;

	if (calibrator->calibration_cancelled)
		return;

	if (compositor->touch_mode == WESTON_TOUCH_MODE_CALIB)
		map_calibrator(calibrator);
}

static void
touch_calibrator_surface_committed(struct wl_listener *listener, void *data)
{
	struct weston_touch_calibrator *calibrator =
		container_of(listener, struct weston_touch_calibrator,
			     surface_commit_listener);
	struct weston_surface *surface = calibrator->surface;

	wl_list_remove(&calibrator->surface_commit_listener.link);
	wl_list_init(&calibrator->surface_commit_listener.link);

	if (surface->width != calibrator->output->width ||
	    surface->height != calibrator->output->height) {
		wl_resource_post_error(calibrator->resource,
				       WESTON_TOUCH_CALIBRATOR_ERROR_BAD_SIZE,
				       "calibrator surface size does not match");
		return;
	}

	weston_compositor_set_touch_mode_calib(calibrator->compositor);
	/* results in call to touch_calibrator_mode_changed() */
}

static void
touch_calibrator_convert(struct wl_client *client,
			 struct wl_resource *resource,
			 int32_t x,
			 int32_t y,
			 uint32_t coordinate_id)
{
	struct weston_touch_calibrator *calibrator;
	struct wl_resource *coordinate_resource;
	struct weston_output *output;
	struct weston_surface *surface;
	uint32_t version;
	struct weston_vector p = { { 0.0, 0.0, 0.0, 1.0 } };
	struct weston_point2d_device_normalized norm;

	version = wl_resource_get_version(resource);
	calibrator = wl_resource_get_user_data(resource);
	surface = calibrator->surface;
	output = calibrator->output;

	coordinate_resource =
		wl_resource_create(client, &weston_touch_coordinate_interface,
				   version, coordinate_id);
	if (!coordinate_resource) {
		wl_client_post_no_memory(client);
		return;
	}

	if (calibrator->calibration_cancelled) {
		weston_touch_coordinate_send_result(coordinate_resource, 0, 0);
		wl_resource_destroy(coordinate_resource);
		return;
	}

	if (!surface || !surface->is_mapped) {
		wl_resource_post_error(resource,
				       WESTON_TOUCH_CALIBRATOR_ERROR_NOT_MAPPED,
				       "calibrator surface is not mapped");
		return;
	}
	assert(calibrator->view);
	assert(output);

	if (x < 0 || y < 0 || x >= surface->width || y >= surface->height) {
		wl_resource_post_error(resource,
				       WESTON_TOUCH_CALIBRATOR_ERROR_BAD_COORDINATES,
				       "convert(%d, %d) input is out of bounds",
				       x, y);
		return;
	}

	/* Convert from surface-local coordinates into global, from global
	 * into output-raw, do perspective division and normalize.
	 */
	weston_view_to_global_float(calibrator->view, x, y, &p.f[0], &p.f[1]);
	weston_matrix_transform(&output->matrix, &p);
	norm.x = p.f[0] / (p.f[3] * output->current_mode->width);
	norm.y = p.f[1] / (p.f[3] * output->current_mode->height);

	if (!normalized_is_valid(&norm)) {
		wl_resource_post_error(resource,
				       WESTON_TOUCH_CALIBRATOR_ERROR_BAD_COORDINATES,
				       "convert(%d, %d) output is out of bounds",
				       x, y);
		return;
	}

	weston_touch_coordinate_send_result(coordinate_resource,
					    wire_uint_from_double(norm.x),
					    wire_uint_from_double(norm.y));
	wl_resource_destroy(coordinate_resource);
}

static void
destroy_touch_calibrator(struct wl_resource *resource)
{
	struct weston_touch_calibrator *calibrator;

	calibrator = wl_resource_get_user_data(resource);

	calibrator->compositor->touch_calibrator = NULL;

	weston_compositor_set_touch_mode_normal(calibrator->compositor);

	if (calibrator->surface) {
		unmap_calibrator(calibrator);
		weston_surface_set_role(calibrator->surface, NULL,
					calibrator->surface->resource, 0);
		wl_list_remove(&calibrator->surface_destroy_listener.link);
		wl_list_remove(&calibrator->surface_commit_listener.link);
	}

	if (calibrator->device)
		wl_list_remove(&calibrator->device_destroy_listener.link);

	if (calibrator->output)
		wl_list_remove(&calibrator->output_destroy_listener.link);

	free(calibrator);
}

static void
touch_calibrator_destroy(struct wl_client *client,
			 struct wl_resource *resource)
{
	wl_resource_destroy(resource);
}

static const struct weston_touch_calibrator_interface
touch_calibrator_implementation = {
	touch_calibrator_destroy,
	touch_calibrator_convert
};

static void
touch_calibrator_cancel_calibration(struct weston_touch_calibrator *calibrator)
{
	weston_touch_calibrator_send_cancel_calibration(calibrator->resource);
	calibrator->calibration_cancelled = true;

	if (calibrator->surface)
		unmap_calibrator(calibrator);
}

static void
touch_calibrator_output_destroyed(struct wl_listener *listener, void *data)
{
	struct weston_touch_calibrator *calibrator =
		container_of(listener, struct weston_touch_calibrator,
			     output_destroy_listener);

	assert(calibrator->output == data);
	calibrator->output = NULL;

	touch_calibrator_cancel_calibration(calibrator);
}

static void
touch_calibrator_device_destroyed(struct wl_listener *listener, void *data)
{
	struct weston_touch_calibrator *calibrator =
		container_of(listener, struct weston_touch_calibrator,
			     device_destroy_listener);

	assert(calibrator->device == data);
	calibrator->device = NULL;

	touch_calibrator_cancel_calibration(calibrator);
}

static void
touch_calibrator_surface_destroyed(struct wl_listener *listener, void *data)
{
	struct weston_touch_calibrator *calibrator =
		container_of(listener, struct weston_touch_calibrator,
			     surface_destroy_listener);

	assert(calibrator->surface->resource == data);

	unmap_calibrator(calibrator);
	calibrator->surface = NULL;
}

static void
touch_calibration_destroy(struct wl_client *client,
			  struct wl_resource *resource)
{
	wl_resource_destroy(resource);
}

static struct weston_touch_device *
weston_compositor_find_touch_device_by_syspath(
	struct weston_compositor *compositor,
	const char *syspath)
{
	struct weston_seat *seat;
	struct weston_touch *touch;
	struct weston_touch_device *device;

	if (!syspath)
		return NULL;

	wl_list_for_each(seat, &compositor->seat_list, link) {
		touch = weston_seat_get_touch(seat);
		if (!touch)
			continue;

		wl_list_for_each(device, &touch->device_list, link) {
			if (strcmp(device->syspath, syspath) == 0)
				return device;
		}
	}

	return NULL;
}

static void
touch_calibration_create_calibrator(
	struct wl_client *client,
	struct wl_resource *touch_calibration_resource,
	struct wl_resource *surface_resource,
	const char *syspath,
	uint32_t calibrator_id)
{
	struct weston_compositor *compositor;
	struct weston_touch_calibrator *calibrator;
	struct weston_touch_device *device;
	struct weston_output *output = NULL;
	struct weston_surface *surface;
	uint32_t version;
	int ret;

	version = wl_resource_get_version(touch_calibration_resource);
	compositor = wl_resource_get_user_data(touch_calibration_resource);

	if (compositor->touch_calibrator != NULL) {
		wl_resource_post_error(touch_calibration_resource,
				WESTON_TOUCH_CALIBRATION_ERROR_ALREADY_EXISTS,
				"a calibrator has already been created");
		return;
	}

	calibrator = zalloc(sizeof *calibrator);
	if (!calibrator) {
		wl_client_post_no_memory(client);
		return;
	}

	calibrator->compositor = compositor;
	calibrator->resource = wl_resource_create(client,
					&weston_touch_calibrator_interface,
					version, calibrator_id);
	if (!calibrator->resource) {
		wl_client_post_no_memory(client);
		goto err_dealloc;
	}

	surface = wl_resource_get_user_data(surface_resource);
	assert(surface);
	ret = weston_surface_set_role(surface, "weston_touch_calibrator",
		touch_calibration_resource,
		WESTON_TOUCH_CALIBRATION_ERROR_INVALID_SURFACE);
	if (ret < 0)
		goto err_destroy_resource;

	calibrator->surface_destroy_listener.notify =
		touch_calibrator_surface_destroyed;
	wl_resource_add_destroy_listener(surface->resource,
					 &calibrator->surface_destroy_listener);
	calibrator->surface = surface;

	calibrator->surface_commit_listener.notify =
		touch_calibrator_surface_committed;
	wl_signal_add(&surface->commit_signal,
		      &calibrator->surface_commit_listener);

	device = weston_compositor_find_touch_device_by_syspath(compositor,
								syspath);
	if (device) {
		output = device->ops->get_output(device);
		if (weston_touch_device_can_calibrate(device) && output)
			calibrator->device = device;
	}

	if (!calibrator->device) {
		wl_resource_post_error(touch_calibration_resource,
				WESTON_TOUCH_CALIBRATION_ERROR_INVALID_DEVICE,
				"the given touch device '%s' is not valid",
				syspath ?: "");
		goto err_unlink_surface;
	}

	calibrator->device_destroy_listener.notify =
		touch_calibrator_device_destroyed;
	wl_signal_add(&calibrator->device->destroy_signal,
		      &calibrator->device_destroy_listener);

	wl_resource_set_implementation(calibrator->resource,
				       &touch_calibrator_implementation,
				       calibrator, destroy_touch_calibrator);

	assert(output);
	calibrator->output_destroy_listener.notify =
		touch_calibrator_output_destroyed;
	wl_signal_add(&output->destroy_signal,
		      &calibrator->output_destroy_listener);
	calibrator->output = output;

	weston_touch_calibrator_send_configure(calibrator->resource,
					       output->width,
					       output->height);

	compositor->touch_calibrator = calibrator;

	return;

err_unlink_surface:
	wl_list_remove(&calibrator->surface_commit_listener.link);
	wl_list_remove(&calibrator->surface_destroy_listener.link);

err_destroy_resource:
	wl_resource_destroy(calibrator->resource);

err_dealloc:
	free(calibrator);
}

static void
touch_calibration_save(struct wl_client *client,
		       struct wl_resource *touch_calibration_resource,
		       const char *device_name,
		       struct wl_array *matrix_data)
{
	struct weston_touch_device *device;
	struct weston_compositor *compositor;
	struct weston_touch_device_matrix calibration;
	struct weston_touch_calibrator *calibrator;
	int i = 0;
	float *c;

	compositor = wl_resource_get_user_data(touch_calibration_resource);

	device = weston_compositor_find_touch_device_by_syspath(compositor,
								device_name);
	if (!device || !weston_touch_device_can_calibrate(device)) {
		wl_resource_post_error(touch_calibration_resource,
				WESTON_TOUCH_CALIBRATION_ERROR_INVALID_DEVICE,
				"the given device is not valid");
		return;
	}

	wl_array_for_each(c, matrix_data) {
		calibration.m[i++] = *c;
	}

	/* If calibration can't be saved, don't set it as current */
	if (compositor->touch_calibration_save &&
	    compositor->touch_calibration_save(compositor, device,
					       &calibration) < 0)
		return;

	/* If calibrator is still mapped, the compositor will use
	 * saved_calibration when going back to normal touch handling.
	 * Continuing calibrating after save request is undefined. */
	calibrator = compositor->touch_calibrator;
	if (calibrator &&
	    calibrator->surface &&
	    weston_surface_is_mapped(calibrator->surface))
		device->saved_calibration = calibration;
	else
		device->ops->set_calibration(device, &calibration);
}

static const struct weston_touch_calibration_interface
touch_calibration_implementation = {
	touch_calibration_destroy,
	touch_calibration_create_calibrator,
	touch_calibration_save
};

static void
bind_touch_calibration(struct wl_client *client,
		       void *data, uint32_t version, uint32_t id)
{
	struct weston_compositor *compositor = data;
	struct wl_resource *resource;
	struct weston_touch_device *device;
	struct weston_seat *seat;
	struct weston_touch *touch;
	const char *name;

	resource = wl_resource_create(client,
				      &weston_touch_calibration_interface,
				      version, id);
	if (resource == NULL) {
		wl_client_post_no_memory(client);
		return;
	}

	wl_resource_set_implementation(resource,
				       &touch_calibration_implementation,
				       compositor, NULL);

	wl_list_for_each(seat, &compositor->seat_list, link) {
		touch = weston_seat_get_touch(seat);
		if (!touch)
			continue;

		wl_list_for_each(device, &touch->device_list, link) {
			if (!weston_touch_device_can_calibrate(device))
				continue;

			name = device->ops->get_calibration_head_name(device);
			if (!name)
				continue;

			weston_touch_calibration_send_touch_device(resource,
							device->syspath, name);
		}
	}
}

/** Advertise touch_calibration support
 *
 * \param compositor The compositor to init for.
 * \param save The callback function for saving a new calibration, or NULL.
 * \return Zero on success, -1 on failure or if already enabled.
 *
 * Calling this initializes the weston_touch_calibration protocol support,
 * so that the interface will be advertised to clients. It is recommended
 * to use some mechanism, e.g. wl_display_set_global_filter(), to restrict
 * access to the interface.
 *
 * There is no way to disable this once enabled.
 *
 * If the save callback is NULL, a new calibration provided by a client will
 * always be accepted. If the save callback is not NULL, it must return
 * success for the new calibration to be accepted.
 */
WL_EXPORT int
weston_compositor_enable_touch_calibrator(struct weston_compositor *compositor,
				weston_touch_calibration_save_func save)
{
	if (compositor->touch_calibration)
		return -1;

	compositor->touch_calibration = wl_global_create(compositor->wl_display,
					&weston_touch_calibration_interface, 1,
					compositor, bind_touch_calibration);
	if (!compositor->touch_calibration)
		return -1;

	compositor->touch_calibration_save = save;
	weston_layer_init(&compositor->calibrator_layer, compositor);

	/* needs to be stacked above everything except lock screen and cursor,
	 * otherwise the position value is arbitrary */
	weston_layer_set_position(&compositor->calibrator_layer,
				  WESTON_LAYER_POSITION_TOP_UI + 120);

	return 0;
}
