/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
/*************************************************************************/
/*                                                                       */
/*                Centre for Speech Technology Research                  */
/*                     University of Edinburgh, UK                       */
/*                        Copyright (c) 1999                             */
/*                        All Rights Reserved.                           */
/*                                                                       */
/*  Permission is hereby granted, free of charge, to use and distribute  */
/*  this software and its documentation without restriction, including   */
/*  without limitation the rights to use, copy, modify, merge, publish,  */
/*  distribute, sublicense, and/or sell copies of this work, and to      */
/*  permit persons to whom this work is furnished to do so, subject to   */
/*  the following conditions:                                            */
/*   1. The code must retain the above copyright notice, this list of    */
/*      conditions and the following disclaimer.                         */
/*   2. Any modifications must be clearly marked as such.                */
/*   3. Original authors' names are not deleted.                         */
/*   4. The authors' names are not used to endorse or promote products   */
/*      derived from this software without specific prior written        */
/*      permission.                                                      */
/*                                                                       */
/*  THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK        */
/*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      */
/*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
/*  SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE     */
/*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    */
/*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   */
/*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          */
/*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       */
/*  THIS SOFTWARE.                                                       */
/*                                                                       */
/*************************************************************************/
/*             Author :  Alan W Black (awb@cstr.ed.ac.uk)                */
/*             Date   :  March 1999                                      */
/*-----------------------------------------------------------------------*/
/*                                                                       */
/* Client end of Festival server API in C designed specifically for      */
/* Galaxy Communicator use though might be of use for other things       */
/*                                                                       */
/* This is a modified version of the standalone client as provided in    */
/* festival example code: festival_client.c                              */
/*                                                                       */
/*=======================================================================*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "gstfestival.h"

static void		gst_festival_class_init		(GstFestivalClass *klass);
static void		gst_festival_init		(GstFestival *festival);

static GstCaps*		text_type_find			(GstBuffer *buf, gpointer private);

static void		gst_festival_chain		(GstPad *pad, GstBuffer *buf);
static GstElementStateReturn 
			gst_festival_change_state 	(GstElement *element);

static FT_Info* 	festival_default_info		(void);
static char*		socket_receive_file_to_buff	(int fd,int *size);
static char*		client_accept_s_expr		(int fd);

/* elementfactory information */
static GstElementDetails gst_festival_details = {
  "Festival synthesizer",
  "Filter/Audio",
  "LGPL",
  "Synthesizes plain text into audio",
  VERSION,
  "Wim Taymans <wim.taymans@chello.be>",
  "(C) 2001",
};

GST_PAD_TEMPLATE_FACTORY (sink_template_factory,
  "festival_sink",
  GST_PAD_SINK,
  GST_PAD_ALWAYS,
  GST_CAPS_NEW (
    "festival_wav",   
    "text/plain",  
    NULL
  )
)

GST_PAD_TEMPLATE_FACTORY (src_template_factory,
  "festival_src",
  GST_PAD_SRC,
  GST_PAD_ALWAYS,
  GST_CAPS_NEW (
    "festival_raw",   
    "audio/raw",  
      "format",            GST_PROPS_STRING ("int"),
       "law",              GST_PROPS_INT (0),
       "endianness",       GST_PROPS_INT (G_BYTE_ORDER),
       "signed",           GST_PROPS_BOOLEAN (TRUE),
       "width",            GST_PROPS_LIST (
	                     GST_PROPS_INT (8),
	                     GST_PROPS_INT (16)
			   ),
       "depth",            GST_PROPS_LIST (
	                     GST_PROPS_INT (8),
	                     GST_PROPS_INT (16)
			   ),
       "rate",             GST_PROPS_INT_RANGE (8000, 48000), 
       "channels",         GST_PROPS_INT_RANGE (1, 2)
  )
)

/* typefactory for 'wav' */
static GstTypeDefinition 
textdefinition = 
{
  "festival_text/plain",
  "text/plain",
  ".txt",
  text_type_find,
};


/* Festival signals and args */
enum {
  /* FILL ME */
  LAST_SIGNAL
};

enum {
  ARG_0,
  /* FILL ME */
};

static GstElementClass *parent_class = NULL;
/*static guint gst_festival_signals[LAST_SIGNAL] = { 0 }; */

GType
gst_festival_get_type (void) 
{
  static GType festival_type = 0;

  if (!festival_type) {
    static const GTypeInfo festival_info = {
      sizeof(GstFestivalClass),      
      NULL,
      NULL,
      (GClassInitFunc) gst_festival_class_init,
      NULL,
      NULL,
      sizeof(GstFestival),
      0,
      (GInstanceInitFunc) gst_festival_init,
    };
    festival_type = g_type_register_static (GST_TYPE_ELEMENT, "GstFestival", &festival_info, 0);
  }
  return festival_type;
}

static void
gst_festival_class_init (GstFestivalClass *klass) 
{
  GstElementClass *gstelement_class;

  gstelement_class = (GstElementClass*) klass;

  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);

  gstelement_class->change_state = gst_festival_change_state;
}

static void 
gst_festival_init (GstFestival *festival) 
{
  festival->sinkpad = gst_pad_new_from_template (
		  GST_PAD_TEMPLATE_GET (sink_template_factory), "sink");
  gst_pad_set_chain_function (festival->sinkpad, gst_festival_chain);
  gst_element_add_pad (GST_ELEMENT (festival), festival->sinkpad);

  festival->srcpad = gst_pad_new_from_template (
		  GST_PAD_TEMPLATE_GET (src_template_factory), "src");
  gst_element_add_pad (GST_ELEMENT (festival), festival->srcpad);

  festival->info = festival_default_info();
}

static GstCaps*
text_type_find (GstBuffer *buf, gpointer private)
{
  gchar *data = GST_BUFFER_DATA (buf);
  gint i;

  for (i=0; i<GST_BUFFER_SIZE (buf); i++) {
    if (!isprint(*(data+i)))
      return NULL;
  }

  return gst_caps_new ("text_type_find", "text/plain", NULL);
}


static void
gst_festival_chain (GstPad *pad, GstBuffer *buf)
{
  gchar *wavefile;
  int filesize;
  FILE *fd;
  char *p;
  char ack[4];
  int n;
  GstFestival *festival;
  GstBuffer *outbuf;
  glong size;

  g_return_if_fail (pad != NULL);
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (buf != NULL);
  g_return_if_fail (GST_BUFFER_DATA (buf) != NULL);

  festival = GST_FESTIVAL (gst_pad_get_parent (pad));
  GST_DEBUG (0, "gst_festival_chain: got buffer in '%s'",
          gst_object_get_name (GST_OBJECT (festival)));

  fd = fdopen(dup(festival->info->server_fd),"wb");
    
  size = GST_BUFFER_SIZE (buf);

  /* Copy text over to server, escaping any quotes */
  fprintf(fd,"(tts_textall \"\n");
  for (p=GST_BUFFER_DATA(buf); p && (*p != '\0') && size; p++, size--)
  {
    if ((*p == '"') || (*p == '\\'))
      putc('\\',fd);
    putc(*p,fd);
  }
  fprintf(fd,"\" \"%s\")\n",festival->info->text_mode);
  fclose(fd);

  /* Read back info from server */
  /* This assumes only one waveform will come back, also LP is unlikely */
  wavefile = NULL;
  do {
    for (n=0; n < 3; )
      n += read(festival->info->server_fd,ack+n,3-n);
    ack[3] = '\0';
    if (strcmp(ack,"WV\n") == 0)         /* receive a waveform */
      wavefile = socket_receive_file_to_buff (festival->info->server_fd, &filesize);
    else if (strcmp(ack,"LP\n") == 0)    /* receive an s-expr */
      client_accept_s_expr(festival->info->server_fd);
    else if (strcmp(ack,"ER\n") == 0)    /* server got an error */
    {
      fprintf(stderr,"festival_client: server returned error\n");
       break;
    }

    if (wavefile) {
      outbuf = gst_buffer_new ();
      GST_BUFFER_DATA (outbuf) = wavefile;
      GST_BUFFER_SIZE (outbuf) = filesize;
      
      if (!GST_PAD_CAPS (festival->srcpad)) {
	gst_pad_try_set_caps (festival->srcpad,
			GST_CAPS_NEW (
				"festival_src",
				"audio/raw",
				  "format",	GST_PROPS_STRING ("int"),
       				  "law",	GST_PROPS_INT (0),
       				  "endianness", GST_PROPS_INT (G_BYTE_ORDER),
       				  "signed",     GST_PROPS_BOOLEAN (TRUE),
       				  "width",      GST_PROPS_INT (16),
       				  "depth",      GST_PROPS_INT (16),
       				  "rate",      	GST_PROPS_INT (16000),
       				  "channels",  	GST_PROPS_INT (1)
				  ));
      }
      gst_pad_push (festival->srcpad, outbuf);

      wavefile = NULL;
    }
  } while (strcmp(ack,"OK\n") != 0);
    
  gst_buffer_unref (buf);
}

static FT_Info*
festival_default_info (void)
{
  FT_Info *info;
  info = (FT_Info *)malloc(1 * sizeof(FT_Info));
    
  info->server_host = FESTIVAL_DEFAULT_SERVER_HOST;
  info->server_port = FESTIVAL_DEFAULT_SERVER_PORT;
  info->text_mode = FESTIVAL_DEFAULT_TEXT_MODE;

  info->server_fd = -1;
    
  return info;
}

static int
festival_socket_open (const char *host, int port)
{   
    /* Return an FD to a remote server */
  struct sockaddr_in serv_addr;
  struct hostent *serverhost;
  int fd;

  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (fd < 0)  
  {
    fprintf(stderr,"festival_client: can't get socket\n");
    return -1;
  }
  memset(&serv_addr, 0, sizeof(serv_addr));
  if ((serv_addr.sin_addr.s_addr = inet_addr(host)) == -1)
  {
    /* its a name rather than an ipnum */
    serverhost = gethostbyname(host);
    if (serverhost == (struct hostent *)0)
    {
      fprintf(stderr,"festival_client: gethostbyname failed\n");
      return -1;
    }
    memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length);
  }
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_port = htons(port);

  if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0)
  {
    fprintf(stderr,"festival_client: connect to server failed\n");
    return -1;
  }

  return fd;
}


static char*
client_accept_s_expr (int fd)
{
  /* Read s-expression from server, as a char * */
  char *expr;
  int filesize;

  expr = socket_receive_file_to_buff(fd,&filesize);
  expr[filesize] = '\0';

  return expr;
}

static char*
socket_receive_file_to_buff (int fd, int *size)
{
  /* Receive file (probably a waveform file) from socket using   */
  /* Festival key stuff technique, but long winded I know, sorry */
  /* but will receive any file without closeing the stream or    */
  /* using OOB data                                              */
  static const char *file_stuff_key = "ft_StUfF_key"; /* must == Festival's key */
  char *buff;
  int bufflen;
  int n,k,i;
  char c;

  bufflen = 1024;
  buff = (char *)malloc(bufflen);
  *size=0;

  for (k=0; file_stuff_key[k] != '\0';)
  {
    n = read(fd,&c,1);
    if (n==0) break;  /* hit stream eof before end of file */
    if ((*size)+k+1 >= bufflen) {
      /* +1 so you can add a NULL if you want */
      bufflen += bufflen/4;
      buff = (char *)realloc(buff,bufflen);
    }
    if (file_stuff_key[k] == c)
      k++;
    else if ((c == 'X') && (file_stuff_key[k+1] == '\0')) { 
      /* It looked like the key but wasn't */
      for (i=0; i < k; i++,(*size)++) 
    	buff[*size] = file_stuff_key[i];
      k=0;
      /* omit the stuffed 'X' */
    }
    else {
      for (i=0; i < k; i++,(*size)++)
    	buff[*size] = file_stuff_key[i];
      k=0;
      buff[*size] = c;
      (*size)++;
    }
  }

  return buff;
}

/***********************************************************************/
/* Public Functions to this API                                        */
/***********************************************************************/

static gboolean
gst_festival_open (GstFestival *festival)
{
  /* Open socket to server */
  if (festival->info == NULL)
    festival->info = festival_default_info();

  festival->info->server_fd = 
    festival_socket_open(festival->info->server_host, festival->info->server_port);
  if (festival->info->server_fd == -1)
    return FALSE;

  return TRUE;
}

static void
gst_festival_close (GstFestival *festival)
{
  if (festival->info == NULL)
    return;

  if (festival->info->server_fd != -1)
    close(festival->info->server_fd);

  return;
}

static GstElementStateReturn
gst_festival_change_state (GstElement *element)
{
  g_return_val_if_fail (GST_IS_FESTIVAL (element), GST_STATE_FAILURE);

  if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
    if (GST_FLAG_IS_SET (element, GST_FESTIVAL_OPEN))
      gst_festival_close (GST_FESTIVAL (element));
  } else {
    if (!GST_FLAG_IS_SET (element, GST_FESTIVAL_OPEN)) {
      if (!gst_festival_open (GST_FESTIVAL (element)))
        return GST_STATE_FAILURE;
    }
  }

  if (GST_ELEMENT_CLASS (parent_class)->change_state)
    return GST_ELEMENT_CLASS (parent_class)->change_state (element);

  return GST_STATE_SUCCESS;
}

static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
  GstElementFactory *factory;
  GstTypeFactory *type;

  /* create an elementfactory for the festival element */
  factory = gst_element_factory_new ("festival", GST_TYPE_FESTIVAL,
                                    &gst_festival_details);
  g_return_val_if_fail(factory != NULL, FALSE);

  /* register src pads */
  gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (sink_template_factory));
  gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (src_template_factory));

  type = gst_type_factory_new (&textdefinition);
  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));

  return TRUE;
}

GstPluginDesc plugin_desc = {
  GST_VERSION_MAJOR,
  GST_VERSION_MINOR,
  "festival",
  plugin_init
};
