/*
 * Copyright © 2012 Intel Corporation
 *
 * 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 "xcursor.h"
#include "wayland-cursor.h"
#include "wayland-client.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>

#include "os-compatibility.h"

#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])

struct shm_pool {
	struct wl_shm_pool *pool;
	int fd;
	unsigned int size;
	unsigned int used;
	char *data;
};

static struct shm_pool *
shm_pool_create(struct wl_shm *shm, int size)
{
	struct shm_pool *pool;

	pool = malloc(sizeof *pool);
	if (!pool)
		return NULL;

	pool->fd = os_create_anonymous_file(size);
	if (pool->fd < 0)
		goto err_free;

	pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
			  pool->fd, 0);

	if (pool->data == MAP_FAILED)
		goto err_close;

	pool->pool = wl_shm_create_pool(shm, pool->fd, size);
	pool->size = size;
	pool->used = 0;

	return pool;

err_close:
	close(pool->fd);
err_free:
	free(pool);
	return NULL;
}

static int
shm_pool_resize(struct shm_pool *pool, int size)
{
	if (ftruncate(pool->fd, size) < 0)
		return 0;

#ifdef HAVE_POSIX_FALLOCATE
	errno = posix_fallocate(pool->fd, 0, size);
	if (errno != 0)
		return 0;
#endif

	wl_shm_pool_resize(pool->pool, size);

	munmap(pool->data, pool->size);

	pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
			  pool->fd, 0);
	if (pool->data == (void *)-1)
		return 0;
	pool->size = size;

	return 1;
}

static int
shm_pool_allocate(struct shm_pool *pool, int size)
{
	int offset;

	if (pool->used + size > pool->size)
		if (!shm_pool_resize(pool, 2 * pool->size + size))
			return -1;

	offset = pool->used;
	pool->used += size;

	return offset;
}

static void
shm_pool_destroy(struct shm_pool *pool)
{
	munmap(pool->data, pool->size);
	wl_shm_pool_destroy(pool->pool);
	close(pool->fd);
	free(pool);
}


struct wl_cursor_theme {
	unsigned int cursor_count;
	struct wl_cursor **cursors;
	struct wl_shm *shm;
	struct shm_pool *pool;
	char *name;
	int size;
};

struct cursor_image {
	struct wl_cursor_image image;
	struct wl_cursor_theme *theme;
	struct wl_buffer *buffer;
	int offset; /* data offset of this image in the shm pool */
};

struct cursor {
	struct wl_cursor cursor;
	uint32_t total_delay; /* length of the animation in ms */
};

/** Get an shm buffer for a cursor image
 *
 * \param image The cursor image
 * \return An shm buffer for the cursor image. The user should not destroy
 * the returned buffer.
 */
WL_EXPORT struct wl_buffer *
wl_cursor_image_get_buffer(struct wl_cursor_image *_img)
{
	struct cursor_image *image = (struct cursor_image *) _img;
	struct wl_cursor_theme *theme = image->theme;

	if (!image->buffer) {
		image->buffer =
			wl_shm_pool_create_buffer(theme->pool->pool,
						  image->offset,
						  _img->width, _img->height,
						  _img->width * 4,
						  WL_SHM_FORMAT_ARGB8888);
	};

	return image->buffer;
}

static void
wl_cursor_image_destroy(struct wl_cursor_image *_img)
{
	struct cursor_image *image = (struct cursor_image *) _img;

	if (image->buffer)
		wl_buffer_destroy(image->buffer);

	free(image);
}

static void
wl_cursor_destroy(struct wl_cursor *cursor)
{
	unsigned int i;

	for (i = 0; i < cursor->image_count; i++)
		wl_cursor_image_destroy(cursor->images[i]);

	free(cursor->images);
	free(cursor->name);
	free(cursor);
}

#include "cursor-data.h"

static struct wl_cursor *
wl_cursor_create_from_data(struct cursor_metadata *metadata,
			   struct wl_cursor_theme *theme)
{
	struct cursor *cursor;
	struct cursor_image *image;
	int size;

	cursor = malloc(sizeof *cursor);
	if (!cursor)
		return NULL;

	cursor->cursor.image_count = 1;
	cursor->cursor.images = malloc(sizeof *cursor->cursor.images);
	if (!cursor->cursor.images)
		goto err_free_cursor;

	cursor->cursor.name = strdup(metadata->name);
	cursor->total_delay = 0;

	image = malloc(sizeof *image);
	if (!image)
		goto err_free_images;

	cursor->cursor.images[0] = (struct wl_cursor_image *) image;
	image->theme = theme;
	image->buffer = NULL;
	image->image.width = metadata->width;
	image->image.height = metadata->height;
	image->image.hotspot_x = metadata->hotspot_x;
	image->image.hotspot_y = metadata->hotspot_y;
	image->image.delay = 0;

	size = metadata->width * metadata->height * sizeof(uint32_t);
	image->offset = shm_pool_allocate(theme->pool, size);

	if (image->offset < 0)
		goto err_free_image;

	memcpy(theme->pool->data + image->offset,
	       cursor_data + metadata->offset, size);

	return &cursor->cursor;

err_free_image:
	free(image);

err_free_images:
	free(cursor->cursor.name);
	free(cursor->cursor.images);

err_free_cursor:
	free(cursor);
	return NULL;
}

static void
load_default_theme(struct wl_cursor_theme *theme)
{
	uint32_t i;

	free(theme->name);
	theme->name = strdup("default");

	theme->cursor_count = ARRAY_LENGTH(cursor_metadata);
	theme->cursors = malloc(theme->cursor_count * sizeof(*theme->cursors));

	if (theme->cursors == NULL) {
		theme->cursor_count = 0;
		return;
	}

	for (i = 0; i < theme->cursor_count; ++i) {
		theme->cursors[i] =
			wl_cursor_create_from_data(&cursor_metadata[i], theme);

		if (theme->cursors[i] == NULL)
			break;
	}
	theme->cursor_count = i;
}

static struct wl_cursor *
wl_cursor_create_from_xcursor_images(XcursorImages *images,
				     struct wl_cursor_theme *theme)
{
	struct cursor *cursor;
	struct cursor_image *image;
	int i, size;

	cursor = malloc(sizeof *cursor);
	if (!cursor)
		return NULL;

	cursor->cursor.images =
		malloc(images->nimage * sizeof cursor->cursor.images[0]);
	if (!cursor->cursor.images) {
		free(cursor);
		return NULL;
	}

	cursor->cursor.name = strdup(images->name);
	cursor->total_delay = 0;

	for (i = 0; i < images->nimage; i++) {
		image = malloc(sizeof *image);
		if (image == NULL)
			break;

		image->theme = theme;
		image->buffer = NULL;

		image->image.width = images->images[i]->width;
		image->image.height = images->images[i]->height;
		image->image.hotspot_x = images->images[i]->xhot;
		image->image.hotspot_y = images->images[i]->yhot;
		image->image.delay = images->images[i]->delay;

		size = image->image.width * image->image.height * 4;
		image->offset = shm_pool_allocate(theme->pool, size);
		if (image->offset < 0) {
			free(image);
			break;
		}

		/* copy pixels to shm pool */
		memcpy(theme->pool->data + image->offset,
		       images->images[i]->pixels, size);
		cursor->total_delay += image->image.delay;
		cursor->cursor.images[i] = (struct wl_cursor_image *) image;
	}
	cursor->cursor.image_count = i;

	if (cursor->cursor.image_count == 0) {
		free(cursor->cursor.name);
		free(cursor->cursor.images);
		free(cursor);
		return NULL;
	}

	return &cursor->cursor;
}

static void
load_callback(XcursorImages *images, void *data)
{
	struct wl_cursor_theme *theme = data;
	struct wl_cursor *cursor;

	if (wl_cursor_theme_get_cursor(theme, images->name)) {
		XcursorImagesDestroy(images);
		return;
	}

	cursor = wl_cursor_create_from_xcursor_images(images, theme);

	if (cursor) {
		theme->cursor_count++;
		theme->cursors =
			realloc(theme->cursors,
				theme->cursor_count * sizeof theme->cursors[0]);

		if (theme->cursors == NULL) {
			theme->cursor_count--;
			free(cursor);
		} else {
			theme->cursors[theme->cursor_count - 1] = cursor;
		}
	}

	XcursorImagesDestroy(images);
}

/** Load a cursor theme to memory shared with the compositor
 *
 * \param name The name of the cursor theme to load. If %NULL, the default
 * theme will be loaded.
 * \param size Desired size of the cursor images.
 * \param shm The compositor's shm interface.
 *
 * \return An object representing the theme that should be destroyed with
 * wl_cursor_theme_destroy() or %NULL on error. If no theme with the given
 * name exists, a default theme will be loaded.
 */
WL_EXPORT struct wl_cursor_theme *
wl_cursor_theme_load(const char *name, int size, struct wl_shm *shm)
{
	struct wl_cursor_theme *theme;

	theme = malloc(sizeof *theme);
	if (!theme)
		return NULL;

	if (!name)
		name = "default";

	theme->name = strdup(name);
	if (!theme->name)
		goto out_error_name;
	theme->size = size;
	theme->cursor_count = 0;
	theme->cursors = NULL;

	theme->pool = shm_pool_create(shm, size * size * 4);
	if (!theme->pool)
		goto out_error_pool;

	xcursor_load_theme(name, size, load_callback, theme);

	if (theme->cursor_count == 0)
		load_default_theme(theme);

	return theme;

out_error_pool:
	free(theme->name);
out_error_name:
	free(theme);
	return NULL;
}

/** Destroys a cursor theme object
 *
 * \param theme The cursor theme to be destroyed
 */
WL_EXPORT void
wl_cursor_theme_destroy(struct wl_cursor_theme *theme)
{
	unsigned int i;

	for (i = 0; i < theme->cursor_count; i++)
		wl_cursor_destroy(theme->cursors[i]);

	shm_pool_destroy(theme->pool);

	free(theme->name);
	free(theme->cursors);
	free(theme);
}

/** Get the cursor for a given name from a cursor theme
 *
 * \param theme The cursor theme
 * \param name Name of the desired cursor
 * \return The theme's cursor of the given name or %NULL if there is no
 * such cursor
 */
WL_EXPORT struct wl_cursor *
wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
			   const char *name)
{
	unsigned int i;

	for (i = 0; i < theme->cursor_count; i++) {
		if (strcmp(name, theme->cursors[i]->name) == 0)
			return theme->cursors[i];
	}

	return NULL;
}

/** Find the frame for a given elapsed time in a cursor animation
 *  as well as the time left until next cursor change.
 *
 * \param cursor The cursor
 * \param time Elapsed time in ms since the beginning of the animation
 * \param duration pointer to uint32_t to store time left for this image or
 *                 zero if the cursor won't change.
 *
 * \return The index of the image that should be displayed for the
 * given time in the cursor animation.
 */
WL_EXPORT int
wl_cursor_frame_and_duration(struct wl_cursor *_cursor, uint32_t time,
			     uint32_t *duration)
{
	struct cursor *cursor = (struct cursor *) _cursor;
	uint32_t t;
	int i;

	if (cursor->cursor.image_count == 1) {
		if (duration)
			*duration = 0;
		return 0;
	}

	i = 0;
	t = time % cursor->total_delay;

	/* If there is a 0 delay in the image set then this
	 * loop breaks on it and we display that cursor until
	 * time % cursor->total_delay wraps again.
	 * Since a 0 delay is silly, and we've never actually
	 * seen one in a cursor file, we haven't bothered to
	 * "fix" this.
	 */
	while (t - cursor->cursor.images[i]->delay < t)
		t -= cursor->cursor.images[i++]->delay;

	if (!duration)
		return i;

	/* Make sure we don't accidentally tell the caller this is
	 * a static cursor image.
	 */
	if (t >= cursor->cursor.images[i]->delay)
		*duration = 1;
	else
		*duration = cursor->cursor.images[i]->delay - t;

	return i;
}

/** Find the frame for a given elapsed time in a cursor animation
 *
 * \param cursor The cursor
 * \param time Elapsed time in ms since the beginning of the animation
 *
 * \return The index of the image that should be displayed for the
 * given time in the cursor animation.
 */
WL_EXPORT int
wl_cursor_frame(struct wl_cursor *_cursor, uint32_t time)
{
	return wl_cursor_frame_and_duration(_cursor, time, NULL);
}
