#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "rfbdecoder.h"
#include "d3des.h"
#include <gst/gst.h>

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

#define RFB_GET_UINT32(ptr) GST_READ_UINT32_BE(ptr)
#define RFB_GET_UINT16(ptr) GST_READ_UINT16_BE(ptr)
#define RFB_GET_UINT8(ptr) GST_READ_UINT8(ptr)

#define RFB_SET_UINT32(ptr, val) GST_WRITE_UINT32_BE((ptr),(val))
#define RFB_SET_UINT16(ptr, val) GST_WRITE_UINT16_BE((ptr),(val))
#define RFB_SET_UINT8(ptr, val) GST_WRITE_UINT8((ptr),(val))

GST_DEBUG_CATEGORY_EXTERN (rfbdecoder_debug);
#define GST_CAT_DEFAULT rfbdecoder_debug


static gboolean rfb_decoder_state_wait_for_protocol_version (RfbDecoder *
    decoder);
static gboolean rfb_decoder_state_wait_for_security (RfbDecoder * decoder);
static gboolean rfb_decoder_state_send_client_initialisation (RfbDecoder *
    decoder);
static gboolean rfb_decoder_state_wait_for_server_initialisation (RfbDecoder *
    decoder);
static gboolean rfb_decoder_state_security_result (RfbDecoder * decoder);
static gboolean rfb_decoder_state_normal (RfbDecoder * decoder);
static gboolean rfb_decoder_state_framebuffer_update (RfbDecoder * decoder);
static gboolean rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder *
    decoder);
static gboolean rfb_decoder_state_set_colour_map_entries (RfbDecoder * decoder);
static gboolean rfb_decoder_state_server_cut_text (RfbDecoder * decoder);
static gboolean rfb_decoder_raw_encoding (RfbDecoder * decoder, gint start_x,
    gint start_y, gint rect_w, gint rect_h);
static gboolean rfb_decoder_copyrect_encoding (RfbDecoder * decoder,
    gint start_x, gint start_y, gint rect_w, gint rect_h);
static gboolean rfb_decoder_rre_encoding (RfbDecoder * decoder, gint start_x,
    gint start_y, gint rect_w, gint rect_h);
static gboolean rfb_decoder_corre_encoding (RfbDecoder * decoder, gint start_x,
    gint start_y, gint rect_w, gint rect_h);
static gboolean rfb_decoder_hextile_encoding (RfbDecoder * decoder,
    gint start_x, gint start_y, gint rect_w, gint rect_h);

RfbDecoder *
rfb_decoder_new (void)
{
  RfbDecoder *decoder = g_new0 (RfbDecoder, 1);

  decoder->socket_client = g_socket_client_new ();
  decoder->connection = NULL;
  decoder->cancellable = g_cancellable_new ();

  decoder->password = NULL;

  decoder->use_copyrect = FALSE;

  decoder->offset_x = 0;
  decoder->offset_y = 0;
  decoder->rect_width = 0;
  decoder->rect_height = 0;
  decoder->shared_flag = TRUE;
  decoder->data = NULL;
  decoder->data_len = 0;
  decoder->error = NULL;

  g_mutex_init (&decoder->write_lock);

  return decoder;
}

void
rfb_decoder_free (RfbDecoder * decoder)
{
  g_return_if_fail (decoder != NULL);

  rfb_decoder_disconnect (decoder);

  g_clear_object (&decoder->socket_client);
  g_clear_object (&decoder->cancellable);
  g_mutex_clear (&decoder->write_lock);
  g_free (decoder);
}

gboolean
rfb_decoder_connect_tcp (RfbDecoder * decoder, gchar * host, guint port)
{
  GError *err = NULL;
  GSocketConnection *connection;

  GST_DEBUG ("connecting to the rfb server");

  g_return_val_if_fail (decoder != NULL, FALSE);
  g_return_val_if_fail (decoder->connection == NULL, FALSE);
  g_return_val_if_fail (host != NULL, FALSE);

  g_cancellable_reset (decoder->cancellable);

  connection =
      g_socket_client_connect_to_host (decoder->socket_client, host, port,
      decoder->cancellable, &err);

  if (!connection)
    goto connect_failed;

  decoder->connection = connection;

  return TRUE;

connect_failed:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG ("Cancelled connecting");
    } else {
      GST_WARNING ("Failed to connect to host '%s:%d': %s", host, port,
          err->message);
      if (decoder->error == NULL) {
        decoder->error = err;
        err = NULL;
      }
    }
    g_clear_error (&err);
    return FALSE;
  }
}

void
rfb_decoder_disconnect (RfbDecoder * decoder)
{
  GST_DEBUG ("Disconnecting from the rfb server");

  g_return_if_fail (decoder);
  g_return_if_fail (decoder->cancellable);

  g_cancellable_cancel (decoder->cancellable);

  /* Make sure threaded write a done first, this avoids race condition,
   * specially when the decoder is freed */
  g_mutex_lock (&decoder->write_lock);

  g_clear_object (&decoder->connection);
  g_clear_error (&decoder->error);
  g_clear_pointer (&decoder->data, g_free);

  g_mutex_unlock (&decoder->write_lock);
}

/**
 * rfb_decoder_iterate:
 * @decoder: The rfb context
 *
 * Initializes the connection with the rfb server
 *
 * Returns: TRUE if initialization was succesfull, FALSE on fail.
 */
gboolean
rfb_decoder_iterate (RfbDecoder * decoder)
{
  gboolean ret;

  g_return_val_if_fail (decoder != NULL, FALSE);
  g_return_val_if_fail (decoder->connection != NULL, FALSE);

  if (decoder->state == NULL) {
    GST_DEBUG ("First iteration: set state to -> wait for protocol version");
    decoder->state = rfb_decoder_state_wait_for_protocol_version;
  }

  GST_DEBUG ("Executing next state in initialization");
  ret = decoder->state (decoder);

  if (ret == FALSE) {
    if (decoder->error == NULL)
      GST_WARNING ("Failure, but no error stored");
    else
      GST_WARNING ("Failure: %s", decoder->error->message);
  }

  return ret;
}

static guint8 *
rfb_decoder_read (RfbDecoder * decoder, guint32 len)
{
  GInputStream *in;
  GError *err = NULL;
  gsize count = 0;

  if (!decoder->connection)
    return FALSE;

  g_return_val_if_fail (len > 0, NULL);

  in = g_io_stream_get_input_stream (G_IO_STREAM (decoder->connection));

  g_return_val_if_fail (in != NULL, NULL);

  if (G_UNLIKELY (len > decoder->data_len)) {
    g_free (decoder->data);
    decoder->data = g_malloc (len);
    decoder->data_len = len;
  }

  if (!g_input_stream_read_all (in, decoder->data, len, &count,
          decoder->cancellable, &err))
    goto recv_error;

  if (count == 0) {
    g_set_error_literal (&err, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE,
        "Connection was closed.");
    goto recv_error;
  }

  return decoder->data;

recv_error:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG ("Read on socket cancelled");
    } else {
      GST_ERROR ("Read error on socket: %s", err->message);
      if (decoder->error == NULL) {
        decoder->error = err;
        err = NULL;
      }
    }
    g_clear_error (&err);
    return NULL;
  }
}

static gboolean
rfb_decoder_send (RfbDecoder * decoder, guint8 * buffer, guint len)
{
  GOutputStream *out;
  GError *err = NULL;

  if (!decoder->connection)
    return FALSE;

  g_return_val_if_fail (buffer != NULL, 0);
  g_return_val_if_fail (len > 0, 0);

  g_mutex_lock (&decoder->write_lock);

  out = g_io_stream_get_output_stream (G_IO_STREAM (decoder->connection));

  if (!g_output_stream_write_all (out, buffer, len, NULL, decoder->cancellable,
          &err))
    goto send_error;

  g_mutex_unlock (&decoder->write_lock);

  return TRUE;

send_error:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG ("Send on socket cancelled");
    } else {
      GST_ERROR ("Send error on socket: %s", err->message);
      if (decoder->error == NULL) {
        decoder->error = err;
        err = NULL;
      }
    }
    g_clear_error (&err);
    g_mutex_unlock (&decoder->write_lock);
    return FALSE;
  }
}

void
rfb_decoder_send_update_request (RfbDecoder * decoder,
    gboolean incremental, gint x, gint y, gint width, gint height)
{
  guint8 data[10];

  g_return_if_fail (decoder != NULL);
  g_return_if_fail (decoder->connection != NULL);

  data[0] = 3;
  data[1] = incremental;
  RFB_SET_UINT16 (data + 2, x);
  RFB_SET_UINT16 (data + 4, y);
  RFB_SET_UINT16 (data + 6, width);
  RFB_SET_UINT16 (data + 8, height);

  rfb_decoder_send (decoder, data, 10);

  /* create a backup of the prev frame for copyrect encoding */
  if (decoder->use_copyrect) {
    memcpy (decoder->prev_frame, decoder->frame,
        decoder->rect_width * decoder->rect_height * decoder->bpp / 8);
  }

  decoder->state = rfb_decoder_state_normal;
}

void
rfb_decoder_send_key_event (RfbDecoder * decoder, guint key, gboolean down_flag)
{
  guint8 data[8];

  g_return_if_fail (decoder != NULL);
  g_return_if_fail (decoder->connection != NULL);

  data[0] = 4;
  data[1] = down_flag;
  RFB_SET_UINT16 (data + 2, 0);
  RFB_SET_UINT32 (data + 4, key);

  rfb_decoder_send (decoder, data, 8);
}

void
rfb_decoder_send_pointer_event (RfbDecoder * decoder,
    gint button_mask, gint x, gint y)
{
  guint8 data[6];

  g_return_if_fail (decoder != NULL);
  g_return_if_fail (decoder->connection != NULL);

  data[0] = 5;
  data[1] = button_mask;
  RFB_SET_UINT16 (data + 2, x);
  RFB_SET_UINT16 (data + 4, y);

  rfb_decoder_send (decoder, data, 6);
}

/**
 * rfb_decoder_state_wait_for_protocol_version:
 *
 * Negotiate the rfb version used
 */
static gboolean
rfb_decoder_state_wait_for_protocol_version (RfbDecoder * decoder)
{
  gchar version_str[] = "RFB 003.003\n";

  if (!rfb_decoder_read (decoder, 12))
    return FALSE;

  g_return_val_if_fail (memcmp (decoder->data, "RFB 003.00", 10) == 0, FALSE);
  g_return_val_if_fail (*(decoder->data + 11) == 0x0a, FALSE);

  GST_DEBUG ("\"%.11s\"", decoder->data);
  *(decoder->data) = 0x00;
  *(decoder->data + 11) = 0x00;
  decoder->protocol_major = atoi ((char *) (decoder->data + 4));
  decoder->protocol_minor = atoi ((char *) (decoder->data + 8));
  GST_DEBUG ("Major version : %d", decoder->protocol_major);
  GST_DEBUG ("Minor version : %d", decoder->protocol_minor);

  if (decoder->protocol_major != 3) {
    GST_INFO
        ("A major protocol version of %d is not supported, falling back to 3",
        decoder->protocol_major);
    decoder->protocol_major = 3;
    decoder->protocol_minor = 3;
  }
  switch (decoder->protocol_minor) {
    case 3:
    case 7:
    case 8:
      break;
    default:
      GST_INFO ("Minor version %d is not supported, using 3",
          decoder->protocol_minor);
      decoder->protocol_minor = 3;
  }

  version_str[10] = '0' + decoder->protocol_minor;

  if (!rfb_decoder_send (decoder, (guint8 *) version_str, 12))
    return FALSE;

  decoder->state = rfb_decoder_state_wait_for_security;
  return TRUE;
}

/*
 * a string describing the reason (where a string is specified as a length
 * followed by that many ASCII characters)
 **/
static gboolean
rfb_decoder_state_reason (RfbDecoder * decoder)
{
  gint reason_length;

  if (!rfb_decoder_read (decoder, 4))
    return FALSE;

  reason_length = RFB_GET_UINT32 (decoder->data);

  if (!rfb_decoder_read (decoder, reason_length))
    return FALSE;

  GST_WARNING ("Reason by server: %s", decoder->data);

  if (decoder->error == NULL) {
    decoder->error = g_error_new (GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ,
        "VNC server error: %s", decoder->data);
  }

  return FALSE;
}

static gboolean
rfb_decoder_state_wait_for_security (RfbDecoder * decoder)
{
  /*
   * Version 3.3 The server decides the security type and sends a single word
   *
   * The security-type may only take the value 0, 1 or 2. A value of 0 means that the
   * connection has failed and is followed by a string giving the reason, as described
   * above.
   */
  if (IS_VERSION_3_3 (decoder)) {
    if (!rfb_decoder_read (decoder, 4))
      return FALSE;

    decoder->security_type = RFB_GET_UINT32 (decoder->data);
    GST_DEBUG ("security = %d", decoder->security_type);

    g_return_val_if_fail (decoder->security_type < 3, FALSE);

    if (decoder->security_type == SECURITY_FAIL) {
      decoder->state = rfb_decoder_state_reason;
      return TRUE;
    }
  } else {
    guint8 num_type;
    gint i;
    guint8 *type = NULL;

    if (!rfb_decoder_read (decoder, 1))
      return FALSE;

    num_type = RFB_GET_UINT8 (decoder->data);
    if (num_type == 0) {
      decoder->state = rfb_decoder_state_reason;
      return TRUE;
    }

    if (!rfb_decoder_read (decoder, num_type))
      return FALSE;

    decoder->security_type = SECURITY_FAIL;

    /* For now, simply pick the first support security method */
    for (i = 0; i < num_type; i++) {
      guint val = RFB_GET_UINT8 (decoder->data + i);

      GST_DEBUG ("Server supports security type %u", val);

      if (val == SECURITY_NONE || val == SECURITY_VNC) {
        decoder->security_type = val;
        type = decoder->data + i;
        break;
      }
    }

    if (!type) {
      GST_WARNING ("Security type negotiation failed.");
      decoder->error = g_error_new (GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ,
          "VNC server requires unsupported security method.");
      return FALSE;
    }

    GST_DEBUG ("security = %d", decoder->security_type);
    if (!rfb_decoder_send (decoder, type, 1))
      return FALSE;
  }

  switch (decoder->security_type) {
    case SECURITY_NONE:
      GST_DEBUG ("Security type is None");
      if (IS_VERSION_3_8 (decoder)) {
        decoder->state = rfb_decoder_state_security_result;
      } else {
        decoder->state = rfb_decoder_state_send_client_initialisation;
      }
      break;
    case SECURITY_VNC:{
      unsigned char key[8], *challenge;
      DESContext des_ctx;
      gsize password_len;

      /*
       * VNC authentication is to be used and protocol data is to be sent
       * unencrypted. The server sends a random 16-byte challenge
       */
      GST_DEBUG ("Security type is VNC Authentication");
      /* VNC Authentication can't be used if the password is not set */
      if (!decoder->password) {
        GST_WARNING
            ("VNC Authentication can't be used if the password is not set");
        decoder->error =
            g_error_new (GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ,
            "VNC servers needs authentication, but no password set");
        return FALSE;
      }

      /* key is 8 bytes and made up of password (padded with 0s if needed) */
      memset (key, 0, 8);
      password_len = strlen (decoder->password);
      memcpy (key, decoder->password, MIN (password_len, 8));

      /* read challenge */
      challenge = rfb_decoder_read (decoder, 16);
      if (challenge == NULL)
        return FALSE;

      /* encrypt 16 challenge bytes in place using key */
      memset (&des_ctx, 0, sizeof (DESContext));
      deskey (&des_ctx, key, EN0);
      des (&des_ctx, challenge, challenge);
      des (&des_ctx, challenge + 8, challenge + 8);

      /* .. and send back to server */
      if (!rfb_decoder_send (decoder, challenge, 16))
        return FALSE;

      GST_DEBUG ("Encrypted challenge sent to server");

      decoder->state = rfb_decoder_state_security_result;
      break;
    }
    default:
      GST_WARNING ("Security type is not known");
      return FALSE;
      break;
  }
  return TRUE;
}

/*
 * The server sends a word to inform the client whether the security handshaking was
 * successful.
 */
static gboolean
rfb_decoder_state_security_result (RfbDecoder * decoder)
{
  if (!rfb_decoder_read (decoder, 4))
    return FALSE;

  if (RFB_GET_UINT32 (decoder->data) != 0) {
    GST_WARNING ("Security handshaking failed");
    if (IS_VERSION_3_8 (decoder)) {
      decoder->state = rfb_decoder_state_reason;
      return TRUE;
    }
    if (decoder->error == NULL) {
      decoder->error = g_error_new (GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ,
          "authentication failed");
    }
    return FALSE;
  }

  GST_DEBUG ("Security handshaking succesful");
  decoder->state = rfb_decoder_state_send_client_initialisation;

  return TRUE;
}

static guint8 *
rfb_decoder_message_set_encodings (GSList * encodings_list)
{

  guint8 *message = g_malloc0 (4 + 4 * g_slist_length (encodings_list));
  guint32 *encoding_type;

  message[0] = 0x02;            /* message type */
  RFB_SET_UINT16 (message + 2, g_slist_length (encodings_list));        /* number of encodings */

  /* write all the encoding types */
  encoding_type = (guint32 *) (message + 4);

  while (encodings_list) {
    RFB_SET_UINT32 (encoding_type, GPOINTER_TO_UINT (encodings_list->data));
    encoding_type++;
    encodings_list = encodings_list->next;
  }

  return message;
}

/*
 * rfb_decoder_state_set_encodings:
 * @decoder: The rfb context
 *
 * Sends the encoding types that the client can decode to the server
 *
 * Returns: TRUE if initialization was succesfull, FALSE on fail.
 */
static gboolean
rfb_decoder_state_set_encodings (RfbDecoder * decoder)
{
  GSList *encoder_list = NULL;
  guint8 *message;

  GST_DEBUG ("entered set encodings");

  encoder_list =
      g_slist_append (encoder_list, GUINT_TO_POINTER (ENCODING_TYPE_HEXTILE));
  encoder_list =
      g_slist_append (encoder_list, GUINT_TO_POINTER (ENCODING_TYPE_CORRE));
  encoder_list =
      g_slist_append (encoder_list, GUINT_TO_POINTER (ENCODING_TYPE_RRE));
  if (decoder->use_copyrect) {
    encoder_list =
        g_slist_append (encoder_list,
        GUINT_TO_POINTER (ENCODING_TYPE_COPYRECT));
  }
  encoder_list =
      g_slist_append (encoder_list, GUINT_TO_POINTER (ENCODING_TYPE_RAW));

  message = rfb_decoder_message_set_encodings (encoder_list);

  if (!rfb_decoder_send (decoder, message,
          4 + 4 * g_slist_length (encoder_list))) {
    g_free (message);
    return FALSE;
  }

  g_free (message);

  decoder->state = rfb_decoder_state_normal;
  decoder->inited = TRUE;

  return TRUE;
}

static gboolean
rfb_decoder_state_send_client_initialisation (RfbDecoder * decoder)
{
  guint8 shared_flag;

  shared_flag = decoder->shared_flag;

  if (!rfb_decoder_send (decoder, &shared_flag, 1))
    return FALSE;

  GST_DEBUG ("shared_flag is %d", shared_flag);

  decoder->state = rfb_decoder_state_wait_for_server_initialisation;
  return TRUE;
}

static gboolean
rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder)
{
  guint32 name_length;

  if (!rfb_decoder_read (decoder, 24))
    return FALSE;

  decoder->width = RFB_GET_UINT16 (decoder->data + 0);
  decoder->height = RFB_GET_UINT16 (decoder->data + 2);
  decoder->bpp = RFB_GET_UINT8 (decoder->data + 4);
  decoder->depth = RFB_GET_UINT8 (decoder->data + 5);
  decoder->big_endian = RFB_GET_UINT8 (decoder->data + 6);
  decoder->true_colour = RFB_GET_UINT8 (decoder->data + 7);
  decoder->red_max = RFB_GET_UINT16 (decoder->data + 8);
  decoder->green_max = RFB_GET_UINT16 (decoder->data + 10);
  decoder->blue_max = RFB_GET_UINT16 (decoder->data + 12);
  decoder->red_shift = RFB_GET_UINT8 (decoder->data + 14);
  decoder->green_shift = RFB_GET_UINT8 (decoder->data + 15);
  decoder->blue_shift = RFB_GET_UINT8 (decoder->data + 16);

  GST_DEBUG ("Server Initialization");
  GST_DEBUG ("width      = %d", decoder->width);
  GST_DEBUG ("height     = %d", decoder->height);
  GST_DEBUG ("bpp        = %d", decoder->bpp);
  GST_DEBUG ("depth      = %d", decoder->depth);
  GST_DEBUG ("big_endian = %d", decoder->big_endian);
  GST_DEBUG ("true_colour= %d", decoder->true_colour);
  GST_DEBUG ("red_max    = %d", decoder->red_max);
  GST_DEBUG ("green_max  = %d", decoder->green_max);
  GST_DEBUG ("blue_max   = %d", decoder->blue_max);
  GST_DEBUG ("red_shift  = %d", decoder->red_shift);
  GST_DEBUG ("green_shift= %d", decoder->green_shift);
  GST_DEBUG ("blue_shift = %d", decoder->blue_shift);

  name_length = RFB_GET_UINT32 (decoder->data + 20);

  if (!rfb_decoder_read (decoder, name_length))
    return FALSE;

  decoder->name = g_strndup ((gchar *) (decoder->data), name_length);
  GST_DEBUG ("name       = %s", decoder->name);

  /* check if we need cropping */

  if (decoder->offset_x > 0) {
    if (decoder->offset_x > decoder->width) {
      GST_WARNING
          ("Trying to crop more than the width of the server.  Setting offset-x to 0.");
      decoder->offset_x = 0;
    } else {
      decoder->width -= decoder->offset_x;
    }
  }
  if (decoder->offset_y > 0) {
    if (decoder->offset_y > decoder->height) {
      GST_WARNING
          ("Trying to crop more than the height of the server. Setting offset-y to 0.");
      decoder->offset_y = 0;
    } else {
      decoder->height -= decoder->offset_y;
    }
  }
  if (decoder->rect_width > 0) {
    if (decoder->rect_width > decoder->width) {
      GST_WARNING
          ("Trying to crop more than the width of the server. Setting width to %u.",
          decoder->width);
      decoder->rect_width = decoder->width;
    } else {
      decoder->width = decoder->rect_width;
    }
  }
  if (decoder->rect_height > 0) {
    if (decoder->rect_height > decoder->height) {
      GST_WARNING
          ("Trying to crop more than the height of the server. Setting height to %u.",
          decoder->height);
      decoder->rect_height = decoder->height;
    } else {
      decoder->height = decoder->rect_height;
    }
  }

  decoder->state = rfb_decoder_state_set_encodings;
  return TRUE;
}

static gboolean
rfb_decoder_state_normal (RfbDecoder * decoder)
{
  gint message_type;

  GST_DEBUG ("decoder_state_normal");

  if (!rfb_decoder_read (decoder, 1))
    return FALSE;

  message_type = RFB_GET_UINT8 (decoder->data);

  switch (message_type) {
    case MESSAGE_TYPE_FRAMEBUFFER_UPDATE:
      GST_DEBUG ("Receiving framebuffer update");
      decoder->state = rfb_decoder_state_framebuffer_update;
      break;
    case 1:
      decoder->state = rfb_decoder_state_set_colour_map_entries;
      break;
    case 2:
      /* bell, ignored */
      decoder->state = rfb_decoder_state_normal;
      break;
    case 3:
      decoder->state = rfb_decoder_state_server_cut_text;
      break;
    default:
      g_critical ("unknown message type %d", message_type);
  }

  return TRUE;
}

static gboolean
rfb_decoder_state_framebuffer_update (RfbDecoder * decoder)
{

  if (!rfb_decoder_read (decoder, 3))
    return FALSE;

  decoder->n_rects = RFB_GET_UINT16 (decoder->data + 1);
  GST_DEBUG ("Number of rectangles : %d", decoder->n_rects);

  decoder->state = rfb_decoder_state_framebuffer_update_rectangle;

  return TRUE;
}

static gboolean
rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
{
  gint x, y, w, h;
  gint encoding;
  gboolean ret = FALSE;

  if (!rfb_decoder_read (decoder, 12))
    return FALSE;

  x = RFB_GET_UINT16 (decoder->data + 0) - decoder->offset_x;
  y = RFB_GET_UINT16 (decoder->data + 2) - decoder->offset_y;
  w = RFB_GET_UINT16 (decoder->data + 4);
  h = RFB_GET_UINT16 (decoder->data + 6);
  encoding = RFB_GET_UINT32 (decoder->data + 8);

  GST_DEBUG ("update recieved");
  GST_DEBUG ("x:%d y:%d", x, y);
  GST_DEBUG ("w:%d h:%d", w, h);
  GST_DEBUG ("encoding: %d", encoding);

  if (((w * h) + (x * y)) > (decoder->width * decoder->height)) {
    GST_ERROR ("Desktop resize is unsupported.");
    decoder->state = NULL;
    return TRUE;
  }

  switch (encoding) {
    case ENCODING_TYPE_RAW:
      ret = rfb_decoder_raw_encoding (decoder, x, y, w, h);
      break;
    case ENCODING_TYPE_COPYRECT:
      ret = rfb_decoder_copyrect_encoding (decoder, x, y, w, h);
      break;
    case ENCODING_TYPE_RRE:
      ret = rfb_decoder_rre_encoding (decoder, x, y, w, h);
      break;
    case ENCODING_TYPE_CORRE:
      ret = rfb_decoder_corre_encoding (decoder, x, y, w, h);
      break;
    case ENCODING_TYPE_HEXTILE:
      ret = rfb_decoder_hextile_encoding (decoder, x, y, w, h);
      break;
    default:
      g_critical ("unimplemented encoding\n");
      break;
  }

  if (!ret)
    return FALSE;

  decoder->n_rects--;
  if (decoder->n_rects == 0) {
    decoder->state = NULL;
  } else {
    decoder->state = rfb_decoder_state_framebuffer_update_rectangle;
  }

  return TRUE;
}

static gboolean
rfb_decoder_raw_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
    gint rect_w, gint rect_h)
{
  gint size;
  guint8 *frame, *p;
  guint32 raw_line_size;

  raw_line_size = rect_w * decoder->bytespp;
  size = rect_h * raw_line_size;

  GST_DEBUG ("Reading %d bytes (%dx%d)", size, rect_w, rect_h);

  if (!rfb_decoder_read (decoder, size))
    return FALSE;

  frame =
      decoder->frame + (((start_y * decoder->rect_width) +
          start_x) * decoder->bytespp);
  p = decoder->data;

  while (rect_h--) {
    memcpy (frame, p, raw_line_size);
    p += raw_line_size;
    frame += decoder->line_size;
  }

  return TRUE;
}

static gboolean
rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
    gint rect_w, gint rect_h)
{
  guint16 src_x, src_y;
  gint line_width, copyrect_width;
  guint8 *src, *dst;

  if (!rfb_decoder_read (decoder, 4))
    return FALSE;

  /* don't forget the offset */
  src_x = RFB_GET_UINT16 (decoder->data) - decoder->offset_x;
  src_y = RFB_GET_UINT16 (decoder->data + 2) - decoder->offset_y;
  GST_DEBUG ("Copyrect from %d %d", src_x, src_y);

  copyrect_width = rect_w * decoder->bytespp;
  line_width = decoder->line_size;
  src =
      decoder->prev_frame + ((src_y * decoder->rect_width) +
      src_x) * decoder->bytespp;
  dst =
      decoder->frame + ((start_y * decoder->rect_width) +
      start_x) * decoder->bytespp;

  while (rect_h--) {
    memcpy (dst, src, copyrect_width);
    src += line_width;
    dst += line_width;
  }

  return TRUE;
}

static void
rfb_decoder_fill_rectangle (RfbDecoder * decoder, gint x, gint y, gint w,
    gint h, guint32 color)
{
  /* fill the whole region with the same color */

  guint32 *offset;
  gint i, j;

  for (i = 0; i < h; i++) {
    offset =
        (guint32 *) (decoder->frame + ((x + (y +
                    i) * decoder->rect_width)) * decoder->bytespp);
    for (j = 0; j < w; j++) {
      *(offset++) = color;
    }
  }
}

static gboolean
rfb_decoder_rre_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
    gint rect_w, gint rect_h)
{
  guint32 number_of_rectangles, color;
  guint16 x, y, w, h;

  if (!rfb_decoder_read (decoder, 4 + decoder->bytespp))
    return FALSE;

  number_of_rectangles = RFB_GET_UINT32 (decoder->data);
  color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data + 4)));

  GST_DEBUG ("number of rectangles :%d", number_of_rectangles);

  /* color the background of this rectangle */
  rfb_decoder_fill_rectangle (decoder, start_x, start_y, rect_w, rect_h, color);

  while (number_of_rectangles--) {

    if (!rfb_decoder_read (decoder, decoder->bytespp + 8))
      return FALSE;

    color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
    x = RFB_GET_UINT16 (decoder->data + decoder->bytespp);
    y = RFB_GET_UINT16 (decoder->data + decoder->bytespp + 2);
    w = RFB_GET_UINT16 (decoder->data + decoder->bytespp + 4);
    h = RFB_GET_UINT16 (decoder->data + decoder->bytespp + 6);

    /* draw the rectangle in the foreground */
    rfb_decoder_fill_rectangle (decoder, start_x + x, start_y + y, w, h, color);
  }

  return TRUE;
}

static gboolean
rfb_decoder_corre_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
    gint rect_w, gint rect_h)
{
  guint32 number_of_rectangles, color;
  guint8 x, y, w, h;

  if (!rfb_decoder_read (decoder, 4 + decoder->bytespp))
    return FALSE;

  number_of_rectangles = RFB_GET_UINT32 (decoder->data);
  color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data + 4)));
  g_free (decoder->data);

  GST_DEBUG ("number of rectangles :%d", number_of_rectangles);

  /* color the background of this rectangle */
  rfb_decoder_fill_rectangle (decoder, start_x, start_y, rect_w, rect_h, color);

  while (number_of_rectangles--) {

    if (!rfb_decoder_read (decoder, decoder->bytespp + 4))
      return FALSE;

    color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
    x = RFB_GET_UINT8 (decoder->data + decoder->bytespp);
    y = RFB_GET_UINT8 (decoder->data + decoder->bytespp + 1);
    w = RFB_GET_UINT8 (decoder->data + decoder->bytespp + 2);
    h = RFB_GET_UINT8 (decoder->data + decoder->bytespp + 3);

    /* draw the rectangle in the foreground */
    rfb_decoder_fill_rectangle (decoder, start_x + x, start_y + y, w, h, color);

    g_free (decoder->data);
  }

  return TRUE;
}

static gboolean
rfb_decoder_hextile_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
    gint rect_w, gint rect_h)
{
  gint32 x, x_count G_GNUC_UNUSED, x_end, x_max, x_max_16;
  gint32 y, y_count G_GNUC_UNUSED, y_end, y_max, y_max_16;
  guint8 subencoding, nr_subrect, xy, wh;
  guint32 background, foreground;

  foreground = background = 0;
  x_end = rect_w % 16;
  x_count = rect_w / 16 + (x_end > 0 ? 1 : 0);
  y_end = rect_h % 16;
  y_count = rect_h / 16 + (y_end > 0 ? 1 : 0);
  x_max = start_x + rect_w;
  y_max = start_y + rect_h;
  x_max_16 = x_max - 16;
  y_max_16 = y_max - 16;

  for (y = start_y; y < y_max; y += 16) {
    for (x = start_x; x < x_max; x += 16) {

      if (!rfb_decoder_read (decoder, 1))
        return FALSE;

      subencoding = RFB_GET_UINT8 (decoder->data);

      if (subencoding & SUBENCODING_RAW) {
        rfb_decoder_raw_encoding (decoder, x, y,
            (x <= x_max_16 ? 16 : x_end), (y <= y_max_16 ? 16 : y_end));
        continue;
      }

      if (subencoding & SUBENCODING_BACKGROUND) {
        if (!rfb_decoder_read (decoder, decoder->bytespp))
          return FALSE;

        background = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
      }
      rfb_decoder_fill_rectangle (decoder, x, y,
          (x <= x_max_16 ? 16 : x_end), (y <= y_max_16 ? 16 : y_end),
          background);

      if (subencoding & SUBENCODING_FOREGROUND) {
        if (!rfb_decoder_read (decoder, decoder->bytespp))
          return FALSE;

        foreground = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
      }

      if (subencoding & SUBENCODING_ANYSUBRECTS) {
        if (!rfb_decoder_read (decoder, 1))
          return FALSE;

        nr_subrect = RFB_GET_UINT8 (decoder->data);
      } else {
        continue;
      }

      if (subencoding & SUBENCODING_SUBRECTSCOLORED) {
        guint offset = 0;

        if (!rfb_decoder_read (decoder, nr_subrect * (2 + decoder->bytespp)))
          return FALSE;

        while (nr_subrect--) {
          foreground =
              GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data + offset)));
          offset += decoder->bytespp;
          xy = RFB_GET_UINT8 (decoder->data + offset++);
          wh = RFB_GET_UINT8 (decoder->data + offset++);
          rfb_decoder_fill_rectangle (decoder, x + (xy >> 4), y + (xy & 0xF),
              1 + (wh >> 4), 1 + (wh & 0xF), foreground);
        }
      } else {
        guint offset = 0;

        if (!rfb_decoder_read (decoder, 2 * nr_subrect))
          return FALSE;

        while (nr_subrect--) {
          xy = RFB_GET_UINT8 (decoder->data + offset++);
          wh = RFB_GET_UINT8 (decoder->data + offset++);
          rfb_decoder_fill_rectangle (decoder, x + (xy >> 4), y + (xy & 0xF),
              1 + (wh >> 4), 1 + (wh & 0xF), foreground);
        }
      }
    }
  }

  return TRUE;
}

static gboolean
rfb_decoder_state_set_colour_map_entries (RfbDecoder * decoder)
{
  g_critical ("not implemented");

  return FALSE;
}

static gboolean
rfb_decoder_state_server_cut_text (RfbDecoder * decoder)
{
  gint cut_text_length;

  /* 3 bytes padding, 4 bytes cut_text_length */
  if (!rfb_decoder_read (decoder, 7))
    return FALSE;

  cut_text_length = RFB_GET_UINT32 (decoder->data + 3);

  if (!rfb_decoder_read (decoder, cut_text_length))
    return FALSE;

  GST_DEBUG ("rfb_decoder_state_server_cut_text: throw away '%s'",
      decoder->data);

  decoder->state = rfb_decoder_state_normal;

  return TRUE;
}
