/*
 * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
 *
 * 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, sub license, 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 NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 <stdlib.h>
#include <string.h>
#ifdef IN_LIBVA
# include "va/wayland/va_wayland.h"
#else
# include <va/va_wayland.h>
#endif
#include "va_display.h"

struct display {
    struct wl_display          *display;
    struct wl_registry         *registry;
    struct wl_compositor       *compositor;
    struct wl_shell            *shell;
    struct wl_shell_surface    *shell_surface;
    struct wl_surface          *surface;
    unsigned int                ref_count;
    int                         event_fd;
};

static struct display *g_display;

static void
registry_handle_global(
    void               *data,
    struct wl_registry *registry,
    uint32_t            id,
    const char         *interface,
    uint32_t            version
)
{
    struct display * const d = data;

    if (strcmp(interface, "wl_compositor") == 0)
        d->compositor =
            wl_registry_bind(registry, id, &wl_compositor_interface, 1);
    else if (strcmp(interface, "wl_shell") == 0)
        d->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
}

static const struct wl_registry_listener registry_listener = {
    registry_handle_global,
    NULL,
};

static VADisplay
va_open_display_wayland(void)
{
    struct display *d;

    if (g_display) {
        d = g_display;
        d->ref_count++;
    } else {
        d = calloc(1, sizeof(*d));
        if (!d)
            return NULL;
        d->event_fd = -1;

        d->display = wl_display_connect(NULL);
        if (!d->display) {
            free(d);
            return NULL;
        }
        wl_display_set_user_data(d->display, d);
        d->registry = wl_display_get_registry(d->display);
        wl_registry_add_listener(d->registry, &registry_listener, d);
        d->event_fd = wl_display_get_fd(d->display);
        wl_display_dispatch(d->display);

        d->ref_count = 1;
        g_display = d;
    }
    return vaGetDisplayWl(d->display);
}

static void
va_close_display_wayland(VADisplay va_dpy)
{
    struct display * const d = g_display;

    if (!d || --d->ref_count > 0)
        return;

    if (d->surface) {
        wl_surface_destroy(d->surface);
        d->surface = NULL;
    }

    if (d->shell_surface) {
        wl_shell_surface_destroy(d->shell_surface);
        d->shell_surface = NULL;
    }

    if (d->shell) {
        wl_shell_destroy(d->shell);
        d->shell = NULL;
    }

    if (d->compositor) {
        wl_compositor_destroy(d->compositor);
        d->compositor = NULL;
    }

    if (d->registry) {
        wl_registry_destroy(d->registry);
        d->registry = NULL;
    }

    if (d->display) {
        wl_display_disconnect(d->display);
        d->display = NULL;
    }
    free(g_display);
    g_display = NULL;
}

static int
ensure_window(VADisplay va_dpy, unsigned int width, unsigned int height)
{
    struct display * const d = g_display;

    if (!d->surface) {
        d->surface = wl_compositor_create_surface(d->compositor);
        if (!d->surface)
            return 0;
    }

    if (!d->shell_surface) {
        d->shell_surface = wl_shell_get_shell_surface(d->shell, d->surface);
        if (!d->shell_surface)
            return 0;
        wl_shell_surface_set_toplevel(d->shell_surface);
    }
    return 1;
}

static VAStatus
va_put_surface_wayland(
    VADisplay          va_dpy,
    VASurfaceID        surface,
    const VARectangle *src_rect,
    const VARectangle *dst_rect
)
{
    struct display * const d = g_display;
    VAStatus va_status;
    struct wl_buffer *buffer;

    if (!ensure_window(va_dpy, dst_rect->width, dst_rect->height))
        return VA_STATUS_ERROR_ALLOCATION_FAILED;

    va_status = vaGetSurfaceBufferWl(va_dpy, surface, VA_FRAME_PICTURE, &buffer);
    if (va_status != VA_STATUS_SUCCESS)
        return va_status;

    wl_surface_attach(d->surface, buffer, 0, 0);
    wl_surface_damage(
        d->surface,
        dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height
    );

    wl_surface_commit(d->surface);
    wl_display_flush(d->display);
    return VA_STATUS_SUCCESS;
}

const VADisplayHooks va_display_hooks_wayland = {
    "wayland",
    va_open_display_wayland,
    va_close_display_wayland,
    va_put_surface_wayland,
};
