/* a tcp client that attaches to the gimpserver */

#include <unistd.h>
#include <stdio.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <glib.h>


static char *line_read = (char *)NULL;
static char *gimp_read = (char *)NULL;
static int   fd = -1;


static char *
get_input (void)
{
  if (line_read)
    {
      free (line_read);
      line_read = (char *)NULL;
    }

  line_read = readline ("> ");

  if (line_read && *line_read)
    {
      add_history (line_read);
    }

  return line_read;
}


static int
disconnect_from_gimp (void)
{
  close (fd);
  fd = -1;
  return 1;
}


static int
connect_to_gimp (void)
{
  struct sockaddr_in sock;
    
  if (fd != -1)
    disconnect_from_gimp ();

  fd = socket (AF_INET, SOCK_STREAM, 0);
  if (fd == -1)
    return -1;

  memset (&sock, 0, sizeof (sock));
  sock.sin_family = AF_INET;
  sock.sin_addr.s_addr = inet_addr ("127.0.0.1");
  sock.sin_port = htons (10008);
  
  if (connect (fd, &sock, sizeof (sock)) != 0)
    return -1;

  return 0;
}



static int
send_to_gimp (void)
{
  unsigned char n;
  
  g_return_val_if_fail (connect_to_gimp () == 0, -1);

  g_return_val_if_fail (write (fd, "G", 1) == 1, -1);

  n = (strlen (line_read) >> 8) & 0xff;
  
  g_return_val_if_fail (write (fd, &n, 1) == 1, -1);
  
  n = strlen (line_read) & 0xff;

  g_return_val_if_fail (write (fd, &n, 1) == 1, -1);

  n = strlen (line_read);

  g_return_val_if_fail (write (fd, line_read, n) == n, -1);

  return 0;
}



static int
read_from_gimp (void)
{
  unsigned char head[4];
  int size;
  int done;
  
  size = 4;
  done = 0;
  while (done < size)
    {
      int nread = read (fd, &head[done], size-done);
      g_return_val_if_fail (nread > 0, -1);
      done += nread;
    }

  g_return_val_if_fail (head[0] == 'G', -1);

  if (head[1] != 0)
    {
      g_warning ("Oops");
    }

  size = (head[2] << 8) + head[3];

  if (gimp_read)
    {
      free (gimp_read);
      gimp_read = (char *)NULL;
    }

  gimp_read = malloc (size+1);

  done = 0;
  while (done < size)
    {
      int nread = read (fd, gimp_read+done, size-done);
      g_return_val_if_fail (nread > 0, -1);
      done += nread;
    }
  gimp_read[size] = '\0';
  
  printf ("received: %s\n", gimp_read);
  fflush (stdout);
  
  return 0;
}



int
main (int argc, char **argv)
{
  while (get_input ())
    {
      if (send_to_gimp () == 0)
        {
          sleep (1);
          read_from_gimp ();
        }
    }
  
  return 0;
}
