/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "guac_cursor.h"
#include "guac_display.h"
#include "guac_surface.h"

#include <guacamole/client.h>
#include <guacamole/socket.h>

#include <stdlib.h>
#include <string.h>

/**
 * Synchronizes all surfaces within the given linked list to the given socket.
 * If the provided pointer to the linked list is NULL, this function has no
 * effect.
 *
 * @param layers
 *     The head element of the linked list of layers to synchronize, which may
 *     be NULL if the list is currently empty.
 *
 * @param user
 *     The user receiving the layers.
 *
 * @param socket
 *     The socket over which each layer should be sent.
 */
static void guac_common_display_dup_layers(guac_common_display_layer* layers,
        guac_user* user, guac_socket* socket) {

    guac_common_display_layer* current = layers;

    /* Synchronize all surfaces in given list */
    while (current != NULL) {
        guac_common_surface_dup(current->surface, user, socket);
        current = current->next;
    }

}

/**
 * Frees all layers and associated surfaces within the given list, as well as
 * their corresponding list elements. If the provided pointer to the linked
 * list is NULL, this function has no effect.
 *
 * @param layers
 *     The head element of the linked list of layers to free, which may be NULL
 *     if the list is currently empty.
 *
 * @param client
 *     The client owning the layers wrapped by each of the layers in the list.
 */
static void guac_common_display_free_layers(guac_common_display_layer* layers,
        guac_client* client) {

    guac_common_display_layer* current = layers;

    /* Free each surface in given list */
    while (current != NULL) {

        guac_common_display_layer* next = current->next;
        guac_layer* layer = current->layer;

        /* Free surface */
        guac_common_surface_free(current->surface);

        /* Destroy layer within remotely-connected client */
        guac_protocol_send_dispose(client->socket, layer);

        /* Free layer or buffer depending on index */
        if (layer->index < 0)
            guac_client_free_buffer(client, layer);
        else if (layer->index > 0)
            guac_client_free_layer(client, layer);

        /* Free current element and advance to next */
        free(current);
        current = next;

    }

}

guac_common_display* guac_common_display_alloc(guac_client* client,
        int width, int height) {

    /* Allocate display */
    guac_common_display* display = malloc(sizeof(guac_common_display));
    if (display == NULL)
        return NULL;

    /* Associate display with given client */
    display->client = client;

    /* Allocate shared cursor */
    display->cursor = guac_common_cursor_alloc(client);

    display->default_surface = guac_common_surface_alloc(client,
            client->socket, GUAC_DEFAULT_LAYER, width, height);

    /* No initial layers or buffers */
    display->layers = NULL;
    display->buffers = NULL;

    return display;

}

void guac_common_display_free(guac_common_display* display) {

    /* Free shared cursor */
    guac_common_cursor_free(display->cursor);

    /* Free default surface */
    guac_common_surface_free(display->default_surface);

    /* Free all layers and buffers */
    guac_common_display_free_layers(display->buffers, display->client);
    guac_common_display_free_layers(display->layers, display->client);

    free(display);

}

void guac_common_display_dup(guac_common_display* display, guac_user* user,
        guac_socket* socket) {

    /* Sunchronize shared cursor */
    guac_common_cursor_dup(display->cursor, user, socket);

    /* Synchronize default surface */
    guac_common_surface_dup(display->default_surface, user, socket);

    /* Synchronize all layers and buffers */
    guac_common_display_dup_layers(display->layers, user, socket);
    guac_common_display_dup_layers(display->buffers, user, socket);

}

void guac_common_display_flush(guac_common_display* display) {
    guac_common_surface_flush(display->default_surface);
}

/**
 * Allocates and inserts a new element into the given linked list of display
 * layers, associating it with the given layer and surface.
 *
 * @param head
 *     A pointer to the head pointer of the list of layers. The head pointer
 *     will be updated by this function to point to the newly-allocated
 *     display layer.
 *
 * @param layer
 *     The Guacamole layer to associated with the new display layer.
 *
 * @param surface
 *     The surface associated with the given Guacamole layer and which should
 *     be associated with the new display layer.
 *
 * @return
 *     The newly-allocated display layer, which has been associated with the
 *     provided layer and surface.
 */
static guac_common_display_layer* guac_common_display_add_layer(
        guac_common_display_layer** head, guac_layer* layer,
        guac_common_surface* surface) {

    guac_common_display_layer* old_head = *head;

    guac_common_display_layer* display_layer =
        malloc(sizeof(guac_common_display_layer));

    /* Init layer/surface pair */
    display_layer->layer = layer;
    display_layer->surface = surface;

    /* Insert list element as the new head */
    display_layer->prev = NULL;
    display_layer->next = old_head;
    *head = display_layer;

    /* Update old head to point to new element, if it existed */
    if (old_head != NULL)
        old_head->prev = display_layer;

    return display_layer;

}

/**
 * Removes the given display layer from the linked list whose head pointer is
 * provided.
 *
 * @param head
 *     A pointer to the head pointer of the list of layers. The head pointer
 *     will be updated by this function if necessary, and will be set to NULL
 *     if the display layer being removed is the only layer in the list.
 *
 * @param display_layer
 *     The display layer to remove from the given list.
 */
static void guac_common_display_remove_layer(guac_common_display_layer** head,
        guac_common_display_layer* display_layer) {

    /* Update previous element, if it exists */
    if (display_layer->prev != NULL)
        display_layer->prev->next = display_layer->next;

    /* If there is no previous element, update the list head */
    else
        *head = display_layer->next;

    /* Update next element, if it exists */
    if (display_layer->next != NULL)
        display_layer->next->prev = display_layer->prev;

}

guac_common_display_layer* guac_common_display_alloc_layer(
        guac_common_display* display, int width, int height) {

    guac_layer* layer;
    guac_common_surface* surface;

    /* Allocate Guacamole layer */
    layer = guac_client_alloc_layer(display->client);

    /* Allocate corresponding surface */
    surface = guac_common_surface_alloc(display->client,
            display->client->socket, layer, width, height);

    /* Add layer and surface to list */
    return guac_common_display_add_layer(&display->layers, layer, surface);

}

guac_common_display_layer* guac_common_display_alloc_buffer(
        guac_common_display* display, int width, int height) {

    guac_layer* buffer;
    guac_common_surface* surface;

    /* Allocate Guacamole buffer */
    buffer = guac_client_alloc_buffer(display->client);

    /* Allocate corresponding surface */
    surface = guac_common_surface_alloc(display->client,
            display->client->socket, buffer, width, height);

    /* Add buffer and surface to list */
    return guac_common_display_add_layer(&display->buffers, buffer, surface);

}

void guac_common_display_free_layer(guac_common_display* display,
        guac_common_display_layer* display_layer) {

    /* Remove list element from list */
    guac_common_display_remove_layer(&display->layers, display_layer);

    /* Free associated layer and surface */
    guac_common_surface_free(display_layer->surface);
    guac_client_free_layer(display->client, display_layer->layer);

    /* Free list element */
    free(display_layer);

}

void guac_common_display_free_buffer(guac_common_display* display,
        guac_common_display_layer* display_buffer) {

    /* Remove list element from list */
    guac_common_display_remove_layer(&display->buffers, display_buffer);

    /* Free associated layer and surface */
    guac_common_surface_free(display_buffer->surface);
    guac_client_free_buffer(display->client, display_buffer->layer);

    /* Free list element */
    free(display_buffer);

}

