/*
 * 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 "config.h"
#include "terminal/scrollbar.h"

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

#include <stdlib.h>

guac_terminal_scrollbar* guac_terminal_scrollbar_alloc(guac_client* client,
        const guac_layer* parent, int parent_width, int parent_height, int visible_area) {

    /* Allocate scrollbar */
    guac_terminal_scrollbar* scrollbar =
        malloc(sizeof(guac_terminal_scrollbar));

    /* Associate client */
    scrollbar->client = client;

    /* Init default min/max and value */
    scrollbar->min   = 0;
    scrollbar->max   = 0;
    scrollbar->value = 0;

    /* Init parent data */
    scrollbar->parent        = parent;
    scrollbar->parent_width  = 0;
    scrollbar->parent_height = 0;
    scrollbar->visible_area  = 0;

    /* Init handle render state */
    scrollbar->render_state.handle_x      = 0;
    scrollbar->render_state.handle_y      = 0;
    scrollbar->render_state.handle_width  = 0;
    scrollbar->render_state.handle_height = 0;

    /* Init container render state */
    scrollbar->render_state.container_x      = 0;
    scrollbar->render_state.container_y      = 0;
    scrollbar->render_state.container_width  = 0;
    scrollbar->render_state.container_height = 0;

    /* Allocate and init layers */
    scrollbar->container = guac_client_alloc_layer(client);
    scrollbar->handle    = guac_client_alloc_layer(client);

    /* Init mouse event state tracking */
    scrollbar->dragging_handle = 0;

    /* Reposition and resize to fit parent */
    guac_terminal_scrollbar_parent_resized(scrollbar,
            parent_width, parent_height, visible_area);

    return scrollbar;

}

void guac_terminal_scrollbar_free(guac_terminal_scrollbar* scrollbar) {

    /* Free layers */
    guac_client_free_layer(scrollbar->client, scrollbar->handle);
    guac_client_free_layer(scrollbar->client, scrollbar->container);

    /* Free scrollbar */
    free(scrollbar);

}

/**
 * Moves the main scrollbar layer to the position indicated within the given
 * scrollbar render state, sending any necessary Guacamole instructions over
 * the given socket.
 *
 * @param scrollbar
 *     The scrollbar to reposition.
 *
 * @param state
 *     The guac_terminal_scrollbar_render_state describing the new scrollbar
 *     position.
 *
 * @param socket
 *     The guac_socket over which any instructions necessary to perform the
 *     render operation should be sent.
 */
static void guac_terminal_scrollbar_move_container(
        guac_terminal_scrollbar* scrollbar,
        guac_terminal_scrollbar_render_state* state,
        guac_socket* socket) {

    /* Send scrollbar position */
    guac_protocol_send_move(socket,
            scrollbar->container, scrollbar->parent,
            state->container_x,
            state->container_y,
            0);

}

/**
 * Resizes and redraws the main scrollbar layer according to the given
 * scrollbar render state, sending any necessary Guacamole instructions over
 * the given socket.
 *
 * @param scrollbar
 *     The scrollbar to resize and redraw.
 *
 * @param state
 *     The guac_terminal_scrollbar_render_state describing the new scrollbar
 *     size and appearance.
 *
 * @param socket
 *     The guac_socket over which any instructions necessary to perform the
 *     render operation should be sent.
 */
static void guac_terminal_scrollbar_draw_container(
        guac_terminal_scrollbar* scrollbar,
        guac_terminal_scrollbar_render_state* state,
        guac_socket* socket) {

    /* Set container size */
    guac_protocol_send_size(socket, scrollbar->container,
            state->container_width,
            state->container_height);

    /* Fill container with solid color */
    guac_protocol_send_rect(socket, scrollbar->container, 0, 0,
            state->container_width,
            state->container_height);

    guac_protocol_send_cfill(socket, GUAC_COMP_SRC, scrollbar->container,
            0x80, 0x80, 0x80, 0x40);

}

/**
 * Moves the handle layer of the scrollbar to the position indicated within the
 * given scrollbar render state, sending any necessary Guacamole instructions
 * over the given socket. The handle is the portion of the scrollbar that
 * indicates the current scroll value and which the user can click and drag to
 * change the value.
 *
 * @param scrollbar
 *     The scrollbar associated with the handle being repositioned.
 *
 * @param state
 *     The guac_terminal_scrollbar_render_state describing the new scrollbar
 *     handle position.
 *
 * @param socket
 *     The guac_socket over which any instructions necessary to perform the
 *     render operation should be sent.
 */
static void guac_terminal_scrollbar_move_handle(
        guac_terminal_scrollbar* scrollbar,
        guac_terminal_scrollbar_render_state* state,
        guac_socket* socket) {

    /* Send handle position */
    guac_protocol_send_move(socket,
            scrollbar->handle, scrollbar->container,
            state->handle_x,
            state->handle_y,
            0);

}

/**
 * Resizes and redraws the handle layer of the scrollbar according to the given
 * scrollbar render state, sending any necessary Guacamole instructions over
 * the given socket. The handle is the portion of the scrollbar that indicates
 * the current scroll value and which the user can click and drag to change the
 * value.
 *
 * @param scrollbar
 *     The scrollbar associated with the handle being resized and redrawn.
 *
 * @param state
 *     The guac_terminal_scrollbar_render_state describing the new scrollbar
 *     handle size and appearance.
 *
 * @param socket
 *     The guac_socket over which any instructions necessary to perform the
 *     render operation should be sent.
 */
static void guac_terminal_scrollbar_draw_handle(
        guac_terminal_scrollbar* scrollbar,
        guac_terminal_scrollbar_render_state* state,
        guac_socket* socket) {

    /* Set handle size */
    guac_protocol_send_size(socket, scrollbar->handle,
            state->handle_width,
            state->handle_height);

    /* Fill handle with solid color */
    guac_protocol_send_rect(socket, scrollbar->handle, 0, 0,
            state->handle_width,
            state->handle_height);

    guac_protocol_send_cfill(socket, GUAC_COMP_SRC, scrollbar->handle,
            0xA0, 0xA0, 0xA0, 0x8F);

}

/**
 * Calculates the state of the scroll bar, given its minimum, maximum, current
 * values, and the state of any dragging operation. The resulting render state
 * will not be reflected graphically unless the scrollbar is flushed, and any
 * resulting value will not be assigned to the scrollbar unless explicitly set
 * with guac_terminal_scrollbar_set_value().
 *
 * @param scrollbar
 *     The scrollbar whose state should be calculated.
 *
 * @param render_state
 *     A pointer to an existing guac_terminal_scrollbar_render_state that will
 *     be populated with the calculated result.
 *
 * @param value
 *     A pointer to an existing int that will be populated with the updated
 *     scrollbar value.
 */
static void calculate_state(guac_terminal_scrollbar* scrollbar,
        guac_terminal_scrollbar_render_state* render_state,
        int* value) {

    /* Use unchanged current value by default */
    *value = scrollbar->value;

    /* Calculate container dimensions */
    render_state->container_width  = GUAC_TERMINAL_SCROLLBAR_WIDTH;
    render_state->container_height = scrollbar->parent_height;

    /* Calculate container position */
    render_state->container_x = scrollbar->parent_width
                              - render_state->container_width;

    render_state->container_y = 0;

    /* Calculate handle dimensions */
    render_state->handle_width  = render_state->container_width
                                - GUAC_TERMINAL_SCROLLBAR_PADDING*2;

    /* Handle can be no bigger than the scrollbar itself */
    int max_handle_height = render_state->container_height
                          - GUAC_TERMINAL_SCROLLBAR_PADDING*2;

    /* Calculate legal delta between scroll values */
    int scroll_delta;
    if (scrollbar->max > scrollbar->min)
        scroll_delta = scrollbar->max - scrollbar->min;
    else
        scroll_delta = 0;

    /* Scale handle relative to visible area vs. scrolling region size */
    int proportional_height = max_handle_height
                            * scrollbar->visible_area
                            / (scroll_delta + scrollbar->visible_area);

    /* Ensure handle is no smaller than minimum height */
    if (proportional_height > GUAC_TERMINAL_SCROLLBAR_MIN_HEIGHT)
        render_state->handle_height = proportional_height;
    else
        render_state->handle_height = GUAC_TERMINAL_SCROLLBAR_MIN_HEIGHT;

    /* Ensure handle is no larger than maximum height */
    if (render_state->handle_height > max_handle_height)
        render_state->handle_height = max_handle_height;

    /* Calculate handle X position */
    render_state->handle_x = GUAC_TERMINAL_SCROLLBAR_PADDING;

    /* Calculate handle Y range */
    int min_handle_y = GUAC_TERMINAL_SCROLLBAR_PADDING;
    int max_handle_y = min_handle_y + max_handle_height
                     - render_state->handle_height;

    /* Position handle relative to mouse if being dragged */
    if (scrollbar->dragging_handle) {

        int dragged_handle_y = scrollbar->drag_current_y
                             - scrollbar->drag_offset_y;

        /* Keep handle within bounds */
        if (dragged_handle_y < min_handle_y)
            dragged_handle_y = min_handle_y;
        else if (dragged_handle_y > max_handle_y)
            dragged_handle_y = max_handle_y;

        render_state->handle_y = dragged_handle_y;

        /* Calculate scrollbar value */
        if (max_handle_y > min_handle_y) {
            *value = scrollbar->min
                   + (dragged_handle_y - min_handle_y)
                      * scroll_delta
                      / (max_handle_y - min_handle_y);
        }

    }

    /* Handle Y position is relative to current scroll value */
    else if (scroll_delta > 0)
        render_state->handle_y = min_handle_y
                               + (max_handle_y - min_handle_y)
                                  * (scrollbar->value - scrollbar->min)
                                  / scroll_delta;

    /* ... unless there is only one possible scroll value */
    else
        render_state->handle_y = GUAC_TERMINAL_SCROLLBAR_PADDING;

}

void guac_terminal_scrollbar_dup(guac_terminal_scrollbar* scrollbar,
        guac_user* user, guac_socket* socket) {

    /* Get old state */
    guac_terminal_scrollbar_render_state* state = &scrollbar->render_state;

    /* Send scrollbar container */
    guac_terminal_scrollbar_draw_container(scrollbar, state, socket);
    guac_terminal_scrollbar_move_container(scrollbar, state, socket);

    /* Send handle */
    guac_terminal_scrollbar_draw_handle(scrollbar, state, socket);
    guac_terminal_scrollbar_move_handle(scrollbar, state, socket);

}

void guac_terminal_scrollbar_flush(guac_terminal_scrollbar* scrollbar) {

    guac_socket* socket = scrollbar->client->socket;

    /* Get old state */
    int old_value = scrollbar->value;
    guac_terminal_scrollbar_render_state* old_state = &scrollbar->render_state;

    /* Calculate new state */
    int new_value;
    guac_terminal_scrollbar_render_state new_state;
    calculate_state(scrollbar, &new_state, &new_value);

    /* Notify of scroll if value is changing */
    if (new_value != old_value && scrollbar->scroll_handler)
        scrollbar->scroll_handler(scrollbar, new_value);

    /* Reposition container if moved */
    if (old_state->container_x != new_state.container_x
     || old_state->container_y != new_state.container_y) {
        guac_terminal_scrollbar_move_container(scrollbar, &new_state, socket);
    }

    /* Resize and redraw container if size changed */
    if (old_state->container_width  != new_state.container_width
     || old_state->container_height != new_state.container_height) {
        guac_terminal_scrollbar_draw_container(scrollbar, &new_state, socket);
    }

    /* Reposition handle if moved */
    if (old_state->handle_x != new_state.handle_x
     || old_state->handle_y != new_state.handle_y) {
        guac_terminal_scrollbar_move_handle(scrollbar, &new_state, socket);
    }

    /* Resize and redraw handle if size changed */
    if (old_state->handle_width  != new_state.handle_width
     || old_state->handle_height != new_state.handle_height) {
        guac_terminal_scrollbar_draw_handle(scrollbar, &new_state, socket);
    }

    /* Store current render state */
    scrollbar->render_state = new_state;

}

void guac_terminal_scrollbar_set_bounds(guac_terminal_scrollbar* scrollbar,
        int min, int max) {

    /* Fit value within bounds */
    if (scrollbar->value > max)
        scrollbar->value = max;
    else if (scrollbar->value < min)
        scrollbar->value = min;

    /* Update bounds */
    scrollbar->min = min;
    scrollbar->max = max;

}

void guac_terminal_scrollbar_set_value(guac_terminal_scrollbar* scrollbar,
        int value) {

    /* Fit value within bounds */
    if (value > scrollbar->max)
        value = scrollbar->max;
    else if (value < scrollbar->min)
        value = scrollbar->min;

    /* Update value */
    scrollbar->value = value;

}

void guac_terminal_scrollbar_parent_resized(guac_terminal_scrollbar* scrollbar,
        int parent_width, int parent_height, int visible_area) {

    /* Assign new dimensions */
    scrollbar->parent_width  = parent_width;
    scrollbar->parent_height = parent_height;
    scrollbar->visible_area  = visible_area;

}

int guac_terminal_scrollbar_handle_mouse(guac_terminal_scrollbar* scrollbar,
        int x, int y, int mask) {

    /* Get container rectangle bounds */
    int parent_left   = scrollbar->render_state.container_x;
    int parent_top    = scrollbar->render_state.container_y;
    int parent_right  = parent_left + scrollbar->render_state.container_width;
    int parent_bottom = parent_top  + scrollbar->render_state.container_height;

    /* Calculate handle rectangle bounds */
    int handle_left   = parent_left + scrollbar->render_state.handle_x;
    int handle_top    = parent_top  + scrollbar->render_state.handle_y;
    int handle_right  = handle_left + scrollbar->render_state.handle_width;
    int handle_bottom = handle_top  + scrollbar->render_state.handle_height;

    /* Handle click on handle */
    if (scrollbar->dragging_handle) {

        /* Update drag while mouse button is held */
        if (mask & GUAC_CLIENT_MOUSE_LEFT)
            scrollbar->drag_current_y = y;

        /* Stop drag if mouse button is released */
        else
            scrollbar->dragging_handle = 0;

        /* Mouse event was handled by scrollbar */
        return 1;

    }
    else if (mask == GUAC_CLIENT_MOUSE_LEFT
            && x >= handle_left && x < handle_right
            && y >= handle_top  && y < handle_bottom) {

        /* Start drag */
        scrollbar->dragging_handle = 1;
        scrollbar->drag_offset_y = y - handle_top;
        scrollbar->drag_current_y = y;

        /* Mouse event was handled by scrollbar */
        return 1;

    }

    /* Eat any events that occur within the scrollbar */
    return x >= parent_left && x < parent_right
        && y >= parent_top  && y < parent_bottom;

}

