/*
   "server_frontend.c" - part of "RAGMAAN, een anagrammengenerator" 

   Copyright (C) 1999 Raymond Zandbergen

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

   The maintainer of this program is Raymond Zandbergen (ray@wirehub.nl)
 */

/*
   This file defines the new Tcl-commands "rm_*"
 */

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <tcl.h>
#include <tk.h>
#include "ragmaan.h"
#include "ipc.h"
#include "glue.h"
#include "server_frontend.h"

/* Hard-coded links to GUI - yuck!  */

#define	GUI_PROGRESS_CANVAS ".p_gauge";
#define	GUI_SEARCH_LIST_BOX ".f_searchlist.lb"
#define	GUI_SEARCH_LIST_BOX_SCROLLBAR ".f_searchlist.sb"

/* # of rectangles in progress bar */

#define	NOF_PROGRESS_STEPS (20)

/* this struct is passed around as the ClientData pointer */

CMD_T *server_cmd = 0;
REPLY_T *server_reply = 0;

/* ---------------------------------------------------------------------

   declarations of all commands

   --------------------------------------------------------------------- */

RM_CMD (rm_server_cache_sync);
RM_CMD (rm_server_create);
RM_CMD (rm_server_destroy);
RM_CMD (rm_server_expand);
RM_CMD (rm_server_filter);
RM_CMD (rm_server_load);
RM_CMD (rm_server_reverse);
RM_CMD (rm_server_search);
RM_CMD (rm_server_sort);
RM_CMD (rm_server_status);

void rm_exit_proc (ClientData clientData);

/* ---------------------------------------------------------------------

   registration procedure

   --------------------------------------------------------------------- */

int
Rms_Init (Tcl_Interp * interp)
{
  Tcl_CreateExitHandler (rm_exit_proc, 0);
  CREATE_CMD (rm_server_cache_sync);
  CREATE_CMD (rm_server_create);
  CREATE_CMD (rm_server_destroy);
  CREATE_CMD (rm_server_expand);
  CREATE_CMD (rm_server_filter);
  CREATE_CMD (rm_server_load);
  CREATE_CMD (rm_server_reverse);
  CREATE_CMD (rm_server_search);
  CREATE_CMD (rm_server_sort);
  CREATE_CMD (rm_server_status);
  return TCL_OK;
}

/* ---------------------------------------------------------------------

   implementation of the actual commands

   --------------------------------------------------------------------- */

int
rm_server_create (ClientData clientData,
		  Tcl_Interp * interp,
		  int argc, char *argv[])
{
  pid_t pid;

  if (argc != 2)
    {
      interp->result = "need server executable name";
      return TCL_ERROR;
    }
  pid = server_create (argv[1], &server_cmd, &server_reply);
  sprintf (interp->result, "%d", pid);
  return TCL_OK;
}

int
rm_server_destroy (ClientData clientData,
		   Tcl_Interp * interp,
		   int argc, char *argv[])
{
  server_destroy ();
  server_cmd = 0;
  server_reply = 0;
  return TCL_OK;
}

int
rm_server_load (ClientData clientData,
		Tcl_Interp * interp,
		int argc, char *argv[])
{
  int progress;

  if (!server_cmd)
    {
      interp->result = "no server";
      return TCL_ERROR;
    }
  if (argc != 2)
    {
      interp->result = "need filename";
      return TCL_ERROR;
    }
  server_cmd->cmd = CMD_LOAD;
  strcpy (server_cmd->string_arg1, argv[1]);
  for (;;)
    {
      server_command (&progress);
      if (progress == -1)
	break;
      rm_progress3 (interp, 0.01 * progress + 0.05);
    }
  rm_progress3 (interp, 0);
  if (server_reply->error)
    {

      strcpy (interp->result, server_reply->string_reply);
      return TCL_ERROR;
    }
  return TCL_OK;
}

int
rm_server_search (ClientData clientData,
		  Tcl_Interp * interp,
		  int argc, char *argv[])
{
  if (!server_cmd)
    {
      interp->result = "no server";
      return TCL_ERROR;
    }
  if (argc != 2)
    {
      interp->result = "need target";
      return TCL_ERROR;
    }
  server_cmd->cmd = CMD_SEARCH;
  strcpy (server_cmd->string_arg1, argv[1]);
  server_command (0);
  if (server_reply->error)
    {

      strcpy (interp->result, server_reply->string_reply);
      return TCL_ERROR;
    }
  sprintf (interp->result, "%d", server_reply->int_reply);
  return TCL_OK;
}

int
rm_server_filter (ClientData clientData,
		  Tcl_Interp * interp,
		  int argc, char *argv[])
{
  if (!server_cmd)
    {
      interp->result = "no server";
      return TCL_ERROR;
    }
  if (argc != 2)
    {
      interp->result = "need regexp";
      return TCL_ERROR;
    }
  server_cmd->cmd = CMD_FILTER;
  strcpy (server_cmd->string_arg1, argv[1]);
  server_command (0);
  if (server_reply->error)
    {

      strcpy (interp->result, server_reply->string_reply);
      return TCL_ERROR;
    }
  sprintf (interp->result, "%d", server_reply->int_reply);
  return TCL_OK;
}

int
rm_server_sort (ClientData clientData,
		Tcl_Interp * interp,
		int argc, char *argv[])
{
  int int_arg;

  if (!server_cmd)
    {
      interp->result = "no server";
      return TCL_ERROR;
    }
  if (argc != 2)
    {
      interp->result = "need boolean";
      return TCL_ERROR;
    }

  if (Tcl_GetBoolean (interp, argv[1], &int_arg) != TCL_OK)
    {

      return TCL_ERROR;
    }
  server_cmd->cmd = CMD_SORT;
  server_cmd->int_arg1 = int_arg;
  server_command (0);
  if (server_reply->error)
    {

      strcpy (interp->result, server_reply->string_reply);
      return TCL_ERROR;
    }
  strcpy (interp->result, server_reply->string_reply);
  return TCL_OK;
}

int
rm_server_reverse (ClientData clientData,
		   Tcl_Interp * interp,
		   int argc, char *argv[])
{
  int int_arg;

  if (!server_cmd)
    {
      interp->result = "no server";
      return TCL_ERROR;
    }
  if (argc != 2)
    {
      interp->result = "need boolean";
      return TCL_ERROR;
    }

  if (Tcl_GetBoolean (interp, argv[1], &int_arg) != TCL_OK)
    {

      return TCL_ERROR;
    }
  server_cmd->cmd = CMD_REVERSE;
  server_cmd->int_arg1 = int_arg;
  server_command (0);
  if (server_reply->error)
    {

      strcpy (interp->result, server_reply->string_reply);
      return TCL_ERROR;
    }
  strcpy (interp->result, server_reply->string_reply);
  return TCL_OK;
}

int
rm_server_expand (ClientData clientData,
		  Tcl_Interp * interp,
		  int argc, char *argv[])
{
  int index;

  if (!server_cmd)
    {
      interp->result = "no server";
      return TCL_ERROR;
    }
  if (argc != 2)
    {
      interp->result = "need index";
      return TCL_ERROR;
    }
  if (Tcl_GetInt (interp, argv[1], &index) != TCL_OK)
    {
      return TCL_ERROR;
    }
  server_cmd->cmd = CMD_EXPAND;
  server_cmd->int_arg1 = index;
  server_command (0);
  if (server_reply->error)
    {

      strcpy (interp->result, server_reply->string_reply);
      return TCL_ERROR;
    }
  strcpy (interp->result, server_reply->string_reply);
  return TCL_OK;
}

int
rm_server_status (ClientData clientData,
		  Tcl_Interp * interp,
		  int argc, char *argv[])
{
  if (!server_cmd)
    {
      interp->result = "no server";
      return TCL_ERROR;
    }
  if (argc > 1)
    {
      interp->result = "trailing args";
      return TCL_ERROR;
    }
  server_cmd->cmd = CMD_STATUS;
  server_command (0);
  if (server_reply->error)
    {

      strcpy (interp->result, server_reply->string_reply);
      return TCL_ERROR;
    }
  Tcl_SetResult (interp, server_reply->string_reply, TCL_VOLATILE);
  return TCL_OK;
}

int
rm_server_cache_sync (ClientData clientData,
		      Tcl_Interp * interp,
		      int argc, char *argv[])
{
  if (!server_cmd)
    {
      interp->result = "no server";
      return TCL_ERROR;
    }
  if (argc > 1)
    {
      interp->result = "trailing args";
      return TCL_ERROR;
    }
  server_cmd->cmd = CMD_CACHE_SYNC;
  server_command (0);
  if (server_reply->error)
    {

      strcpy (interp->result, server_reply->string_reply);
      return TCL_ERROR;
    }
  strcpy (interp->result, server_reply->string_reply);
  return TCL_OK;
}

void
rm_exit_proc (ClientData clientData)
{
  cleanup ();
}
