/*
 * Copyright © 2016 Quentin "Sardem FF7" Glidic
 *
 * 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.
 */
/*
 * (C) Copyright 2014, Fuji Xerox Co.,Ltd.  All rights reserved.
 * File name : weston-fx-shell.h
 * Title : shell common data 
 */

#include "config.h"

#include <string.h>

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

#include "shared/helpers.h"
#include "compositor.h"
#include "zalloc.h"

#include "fx-client.h"
#include "fx-surface.h"
#include "fx-wl-shell.h"
#include "weston-fx-shell.h"

/* Typedefs */
struct weston_fx_shell {
    struct weston_compositor *
        compositor;
    struct weston_fx_shell_api
        api;
    void *
        user_data;
    struct wl_global *
        wl_shell;
};

/* Procedures */
WL_EXPORT struct weston_fx_shell *
weston_fx_shell_create(
        struct weston_compositor *compositor,
        const struct weston_fx_shell_api *api,
        void *user_data )
{
    struct weston_fx_shell *weston_fx_shell;
    struct wl_display *display = compositor->wl_display;

    assert( api->surface_added );
    assert( api->surface_removed );

    weston_fx_shell = zalloc( sizeof( struct weston_fx_shell ) );
    weston_fx_shell->compositor = compositor;
    weston_fx_shell->user_data = user_data;

    weston_fx_shell->api.struct_size =
        MIN(    sizeof( struct weston_fx_shell_api ),
                api->struct_size );
    memcpy( &weston_fx_shell->api,
            api,
            weston_fx_shell->api.struct_size );

    weston_fx_shell->wl_shell =
        fx_shell_wl_shell_create(
                weston_fx_shell,
                display );
    if ( weston_fx_shell->wl_shell == NULL ) {
        weston_fx_shell_destroy( weston_fx_shell );
        return NULL;
    }

    return weston_fx_shell;
}
WL_EXPORT void
weston_fx_shell_destroy( struct weston_fx_shell *weston_fx_shell )
{
    if ( weston_fx_shell == NULL ) {
        return;
    }

    if ( weston_fx_shell->wl_shell != NULL ) {
        wl_global_destroy( weston_fx_shell->wl_shell );
    }

    free( weston_fx_shell );
}

struct weston_compositor *
weston_fx_shell_get_compositor( struct weston_fx_shell *weston_fx_shell )
{
    return weston_fx_shell->compositor;
}
struct wl_display *
weston_fx_shell_get_display( struct weston_fx_shell *weston_fx_shell )
{
    return weston_fx_shell->compositor->wl_display;
}
void
weston_fx_shell_api_surface_added(
        struct weston_fx_shell *weston_fx_shell,
        struct fx_shell_surface *shell_surface )
{
    struct fx_shell_client *shell_client =
        fx_shell_surface_get_client( shell_surface );
    struct wl_list *list =
        fx_shell_client_get_surface_list( shell_client );
    struct wl_list *link = fx_shell_surface_get_client_link( shell_surface );

    weston_fx_shell->api.surface_added(
            shell_surface,
            weston_fx_shell->user_data );
    wl_list_insert(
            list,
            link );
}
void
weston_fx_shell_api_surface_removed(
        struct weston_fx_shell *weston_fx_shell,
        struct fx_shell_surface *shell_surface )
{
    struct wl_list *link = fx_shell_surface_get_client_link( shell_surface );

    wl_list_remove( link );
    wl_list_init( link );
    weston_fx_shell->api.surface_removed(
            shell_surface,
            weston_fx_shell->user_data );
}
void
weston_fx_shell_api_committed(
        struct weston_fx_shell *weston_fx_shell,
        struct fx_shell_surface *shell_surface,
        int32_t sx,
        int32_t sy )
{
    if ( weston_fx_shell->api.committed != NULL ) {
        weston_fx_shell->api.committed(
                shell_surface,
                sx,
                sy,
                weston_fx_shell->user_data );
    }
}
void
weston_fx_shell_api_set_parent(
        struct weston_fx_shell *weston_fx_shell,
        struct fx_shell_surface *surface,
        struct fx_shell_surface *parent_shell_surface )
{
    if ( weston_fx_shell->api.set_parent != NULL ) {
        weston_fx_shell->api.set_parent(
                surface,
                parent_shell_surface,
                weston_fx_shell->user_data );
    }
}
void
weston_fx_shell_api_fullscreen_requested(
        struct weston_fx_shell *weston_fx_shell,
        struct fx_shell_surface *shell_surface,
        bool fullscreen,
        struct weston_output *output)
{
    if ( weston_fx_shell->api.fullscreen_requested != NULL ) {
        weston_fx_shell->api.fullscreen_requested(
                shell_surface,
                fullscreen,
                output,
                weston_fx_shell->user_data );
    }
}
