/*******************************************************************
* emcspy.c, event spying and recording task. Spys the streams
* of sub-event from the data form the builder multiple circular 
* buffer. All the work is done in emcspy_lib.c.
********************************************************************
#define DEBUG_VAR
#define DEBUG_ON
*/

#include <stdio.h>
#include <time.h>
#include <string.h>

#include "Error.h"

#include "template.h"
#define THIS_IS_THE_MAIN
#include "emcspy.h"
#include "l2defs.h"

int Process_Event ();
void Process_Idle ();

extern char ownpname[];

/****************************************************************
 * Main - main procedure of the collector
 *
 * main(argc, argv) is the main procedure of the collector. It  
 * calls the template with the addresses of the Any_Event() and
 * Process_Event() procedures.                                  
 *****************************************************************/

void
main (argc, argv)
     int argc;
     char *argv[];
{
#ifdef DEBUG_VAR
  int i;
  short stpe;
  char *value;
#endif

  if (Template_Init (get_name_from_args (argc, argv)) < 0)
    {
      printf ("Process of name %s already exists\n",
	      get_name_from_args (argc, argv));
      printf ("Please use -n to set a different name\n");
      exit (0);
    }

#ifdef DEBUG_VAR
  for (i = 0; i < var_number_usr; i++)
    {
      value= (char *)(var_dict_usr[i].addr);
      var_read_value(ownpname,var_dict_usr[i].name,&stpe,value);
      if (stpe==STRING)
	printf("%s:  %s, type %d, value %s \n",
               ownpname,  var_dict_usr[i].name,stpe, value );
      else if(stpe==INTEGER)
	printf("%s:  %s, type %d, value %d \n",
               ownpname,  var_dict_usr[i].name,stpe, *(int*)value );
      else
	printf("%s:  %s, type %d, value %f \n",
               ownpname,  var_dict_usr[i].name,stpe, *(float*)value );
    }
#endif
  
  /*** reset runstate to a default, idle, value.    ***/
  ask_var.runstate = UNDEFINED_STATE;
  var_set_value ("runstate", &ask_var.runstate);

  /*==============================================================*/

  if (EmcspyInit(&ask_var) == Error_YES)
    {
      Exit (ownpname, " ");
      exit(1);
    }

  /*==============================================================*/

  /*
  Template_Main( (int (*)()) Process_Event  , NULL, 
		 (void (*)()) Process_Idle); 
  */
  Template_Main ((int (*)()) Process_Event, NULL, NULL);
}


/******************************************************************
 * Process_Event - calls the corresponding procedure of an event
 *
 * Process_Event() calls the corresponding procedure            
 * for a given event.  
 ******************************************************************/

int 
Process_Event ()
{
  DEBUG2 (("emcspy/Process_Event> IN\n"));

  if (ask_var.runstate == INIT_STATE)
    {
    }
  else if (ask_var.runstate == UNDEFINED_STATE)
    {
      idle (10);
    }
  else if (ask_var.runstate == PAUSE_STATE)
    {
      idle (1);
    }

  if (ask_var.runstate == RUNNING_STATE)
    {
      /*==============================================================*/

      if ( EmcspyProcess(&ask_var) == Error_YES)
	return (FALSE);
      
      /*==============================================================*/
    }

  DEBUG2 (("emcspy/Process_Event> OUT\n"));

  return (TRUE);
}

/***************************************************************
 * Begin - processes a begin command
 *
 * Begin(header, arg_string) processes a begin command.         
 * header: the name of the process which sends the begin cmnd,  
 * arg_string: the arguments of the begin command.   
 ***************************************************************/

int 
Begin (header, arg_string)
     char *header, *arg_string;
{
  DEBUG(("emcspy/Begin> IN \n"));

  /*** put variables to the status path ***/
  var_set_all_values();

  /*
   *   Check and correct the current state
   */
  if (ask_var.runstate==INIT_STATE || ask_var.runstate==RUNNING_STATE)
    {
      Pause ("", "");
      End ("", "");
    }
  else if (ask_var.runstate == PAUSE_STATE)
    {
      End ("", "");
    }
  
  /*==============================================================*/
  /* user_begin() */
  
  ask_var.runstate = INIT_STATE;

  /* we confirm the command reception immediately.
   */
  Update_Command_Status(DONE);

  if (EmcspyBegin(&ask_var) == Error_YES)
    return(FALSE);
  
  /*==============================================================*/
  

  /*** put variables to the status path ***/
  var_set_all_values();
  
  DEBUG(("emcspy/Begin> OUT \n"));
  return (TRUE);
}

/*************************************************************
 * Pause - processes a pause command
 * 
 * Pause(header, arg_string) processes a pause command.         
 * header: the name of the process which sends the pause cmnd,  
 * arg_string: the arguments of the end command.              
 *************************************************************/

int 
Pause (header, comment_string)
     char *header, *comment_string;
{
  int t;

  DEBUG(("emcspy/Pause> IN \n"));

  /* allow PAUSE even if in PAUSE state */
  if ((ask_var.runstate == UNDEFINED_STATE))
    {
      printf ("Invalid state transition...\n");
      return (TRUE);
    }

  ask_var.runstate = PAUSE_STATE;

  /*** put variables to the status path ***/
  var_set_all_values();
  Update_Command_Status(DONE);

  DEBUG(("emcspy/Pause> OUT \n"));

  return (TRUE);
}


/*************************************************************
 * Resume - processes a resume command
 * 
 * Resume(header, arg_string) processes a resume command.         
 * header: the name of the process which sends the resume cmnd,  
 * arg_string: the arguments of the resume command.              
 *************************************************************/

int 
Resume (header, comment_string)
     char *header, *comment_string;
{
  DEBUG(("emcspy/Resume> IN \n"));

  if (ask_var.runstate == UNDEFINED_STATE)
    {
      printf ("Invalid state transition...\n");
      return (TRUE);
    }

  ask_var.runstate = RUNNING_STATE;

  /*** put variables to the status path ***/
  var_set_all_values();
  Update_Command_Status(DONE);

  DEBUG(("emcspy/Resume> OUT \n"));
  return (TRUE);
}


/*************************************************************
 * End - processes an end command
 * 
 * End(header, arg_string) processes a end command.         
 * header: the name of the process which sends the end cmnd,  
 * arg_string: the arguments of the end command.              
 *************************************************************/

int 
End (header, comment_string)
     char *header, *comment_string;
{
  DEBUG(("emcspy/End> IN \n"));
  /*
   *   Check and correct the current state.
   */
  if (ask_var.runstate == UNDEFINED_STATE)
    {
      EmcspyEnd(&ask_var); /* should be already done */
      return (TRUE);
    }
  else if (ask_var.runstate==INIT_STATE || ask_var.runstate==RUNNING_STATE)
    {
      Pause ("", "");
    }
  
  ask_var.runstate = UNDEFINED_STATE;
  
  /*** put variables to the status path ***/
  var_set_all_values();
  Update_Command_Status(DONE);

  DEBUG(("emcspy/End> OUT \n"));

  return (TRUE);
}


/********************************************************************
 * Exit - processes an exit command
 *
 * Exit(header, arg_string) processes an exit command.
 * header:     the name of the process which sends the exit command,
 * arg_string: the arguments of the exit command.
 *********************************************************************/

int 
ExitC (header, arg_string)
     char *header, *arg_string;
{
  DEBUG(("emcspy/ExitC> IN \n"));

  End ("", "");
  /*
  if (Delete_Sem(event_semid) == UNIDAQ_ERROR)
    if (debug_level >= 10) printf("Error in Delete_Sem()\n"); 
  */

  /*user_exit ();*/

  DEBUG(("emcspy/ExitC> OUT \n"));

  Exit (ownpname, " ");

  exit(1);

/*   return (Exit (ownpname, " ")); */
}


void 
Process_Idle ()
{

  /*
  DEBUG(("emcspy/Process_Idle> IN \n"));
  DEBUG(("emcspy/Process_Idle> OUT \n"));
  */
  sleep (10);

  return;
}

int 
Status (header, comment_string)
     char *header, *comment_string;
{
  DEBUG(("emcspy/Status> IN \n"));

  EmcspyStatus(&ask_var);

  /*** put variables to the status path ***/
  var_set_all_values();

  Update_Command_Status(DONE);

  DEBUG(("emcspy/Update> OUT \n"));

  return (TRUE);
}