#include "snd.h"

static XtInputId clm_id = 0;

void CLM_disconnect(snd_state *ss)
{
  if (clm_id) 
    {
      XtRemoveInput(clm_id);
      if (ss->to_clm)
	write(ss->to_clm,"(stop-snd t)",13);
      clm_id = 0;
    }
  if (ss->to_clm) close(ss->to_clm);
  ss->to_clm = 0;
}

static void GetClmString (XtPointer clientData, int *fd, XtInputId *id)
{
  get_clm_string((snd_state *)clientData,*fd,TRUE);
}

static char connected_msg[] = "(print \"Snd connected\")";

static char *user_dir_fifo(char *fifo)
{
  char *file_name_buf;
  file_name_buf = (char *)calloc(128,sizeof(char*));
  if (getenv("HOME"))
    strcpy(file_name_buf,getenv("HOME"));
  else 
#ifdef CCRMA
    strcpy(file_name_buf,"/zap");
#else
    strcpy(file_name_buf,"/tmp");
#endif
  strcat(file_name_buf,"/");
  strcat(file_name_buf,fifo);
  return(file_name_buf);
}

int CLM_connect(snd_state *ss)
{
  /* look for CLM fifo -- if found, establish connection and X input callback */
  state_context *sx;
  int bytes,len;
  char *errmsg;
  char *clm_snd = NULL,*snd_clm = NULL;
#ifndef WINDOZE
  sx = ss->sgx;
  clm_snd = user_dir_fifo(CLM_SND_FIFO);
  snd_clm = user_dir_fifo(SND_CLM_FIFO);
  ss->from_clm = open(clm_snd,O_RDWR,0);
  if (ss->from_clm != -1)
    {
      ss->to_clm = open(snd_clm,O_RDWR,0);
      clm_id = XtAppAddInput(sx->mainapp,ss->from_clm,(XtPointer)XtInputReadMask,GetClmString,(XtPointer)ss);
      /* now tell CLM we're here (it is waiting...) */
      len = strlen(connected_msg)+1;
      bytes = write(ss->to_clm,connected_msg,len);
      if (bytes != len)
	{
	  errmsg = (char *)calloc(64,sizeof(char));
	  sprintf(errmsg,"attempt to reply to CLM failed! (%d != %d, %s)",bytes,len,strerror(errno));
	  snd_printf(ss,errmsg);
	  free(errmsg);
	}
    }
  else 
    {
      ss->to_clm = 0;
      clm_id = 0;
    }
#endif
  free(clm_snd);
  free(snd_clm);
  return(0);
}

/* now the "clm is awaiting snd data" dialog */

static Widget clm_fd = NULL;
static char *clm_added_help = NULL;

static void clm_help_callback(Widget w,XtPointer clientData,XtPointer callData) 
{
  snd_state *ss = (snd_state *)clientData;
  ssnd_help(ss,
	    "CLM Snd",
"CLM is awaiting a response from Snd.  If\n\
you click 'ok', the current changed data will\n\
be sent.  Click 'cancel' to cancel the\n\
transaction.\n\
\n\
",
clm_added_help,
NULL);
}

void cleanup_clm_dialog(snd_state *ss)
{
  if ((clm_fd) && (XtIsManaged(clm_fd)))
    {
      write(ss->to_clm,":cancel",8);
      XtUnmanageChild(clm_fd);
    }
}

static void clm_cancel_callback(Widget w,XtPointer clientData,XtPointer callData) 
{
  snd_state *ss = (snd_state *)clientData;
  write(ss->to_clm,":cancel",8);
}

static void clm_ok_callback(Widget w,XtPointer clientData,XtPointer callData) 
{
  snd_state *ss = (snd_state *)clientData;
  write(ss->to_clm,":ok",4);
}

void start_clm_dialog(snd_state *ss, char *msg, char *help)
{
  Arg args[20];
  int n;
  XmString xmstr1,xmstr2,xmstr3,xmstr4,titlestr;
  clm_added_help = help;
  if (!clm_fd)
    {
      /* create dialog */
      n=0;
      if (!(ss->using_schemes)) n = background_main_color(args,n,ss);
      xmstr1=XmStringCreateLocalized(msg);
      xmstr2=XmStringCreateLocalized(snd_string_Ok);
      xmstr3=XmStringCreateLocalized(snd_string_Cancel);
      xmstr4=XmStringCreateLocalized(snd_string_Help);
      titlestr = XmStringCreateLocalized(snd_string_CLM);
      XtSetArg(args[n],XmNmessageString,xmstr1); n++;
      XtSetArg(args[n],XmNokLabelString,xmstr2); n++;
      XtSetArg(args[n],XmNcancelLabelString,xmstr3); n++;
      XtSetArg(args[n],XmNhelpLabelString,xmstr4); n++;
      XtSetArg(args[n],XmNdialogTitle,titlestr); n++;
#if RESIZE_DIALOG
      XtSetArg(args[n],XmNresizePolicy,XmRESIZE_GROW); n++;
      XtSetArg(args[n],XmNnoResize,FALSE); n++;
#endif
#if UNSET_TRANSIENT
      XtSetArg(args[n],XmNtransient,FALSE); n++;
#endif
      clm_fd = XmCreateMessageDialog(main_PANE(ss),"clm",args,n);
#if UNSET_TRANSIENT
      add_dialog(ss,clm_fd);
#endif
      XmStringFree(xmstr1);
      XmStringFree(xmstr2);
      XmStringFree(xmstr3);
      XmStringFree(xmstr4);
      XmStringFree(titlestr);
      XtUnmanageChild(XmMessageBoxGetChild(clm_fd,XmDIALOG_SYMBOL_LABEL));
      XtAddCallback(clm_fd,XmNhelpCallback,clm_help_callback,ss);
      XtAddCallback(clm_fd,XmNcancelCallback,clm_cancel_callback,ss);
      XtAddCallback(clm_fd,XmNokCallback,clm_ok_callback,ss);
#if MANAGE_DIALOG
      XtManageChild(clm_fd);
#endif
      if (!(ss->using_schemes)) map_over_children(clm_fd,set_main_color_of_widget,(void *)ss);
    }
  else
    {  
      xmstr1=XmStringCreateLocalized(msg);
      XtVaSetValues(clm_fd,XmNmessageString,xmstr1,NULL);
      XmStringFree(xmstr1);      
    }
  if (!(XtIsManaged(clm_fd))) XtManageChild(clm_fd);
}
