/*
 * receive_pattern.c
 *
 * Copyright (c) 1992 Sun Microsystems, Inc.  All rights reserved.
 */

#include <xview/xview.h>
#include <xview/panel.h>
#include <desktop/tt_c.h>
#include <unistd.h>
#include "chkrc.h"
#include "tt_enum_xlate.h"
#include "pat_ui.h"
#include "arg_edit.h"
#include "ttsnoop.h"

#define IF_SET(val, i)	(val&(1<<i))

extern int	trace_on;

char **str_arrayadd (a, s)
char **a;
char  *s;
{
  register int    i = 0;
  register char **p = a;
     
  if (s) /* there's something to add */
    { 
    if (a) 
       { /* if a is already allocated
        for (i=0; *p++; i++); /* find out how large we are now */
        /* increase the size of a by one */
        a = (char **)realloc(a, (i + 2) * sizeof(char *)); 
       }
    else  /* initially, set to size of two (with NULL termination) */
      a = (char **)malloc(2 * sizeof(char *));
 
    a [i] = strdup(s);
    a [i+1] = NULL;
    }  
     
  return a;
}

pattern_init(pat_receive_msg_popup_objects *ip)
{
	xv_set(ip->mode_setting, PANEL_CLIENT_DATA, -1, NULL);
}

/* set_pattern() - registers message patterns you are interested in. */
set_pattern(pat_receive_msg_popup_objects *ip)
{
	extern	Notify_value	pat_receive();
	static  Tt_pattern      tt_pat = NULL;
	int		fd;
	char		*procid;
	char		*session;
	char		*file;
	char		*name;
	int		i, num;
	int		setting;
	char *		buff, *c;
	Arg_list	*arg;
	int		scope_value;
	char		**file_names = (char **)NULL;

	if (trace_on) {
	        printf("\n--------------- Pattern Code -------------------------\n");
		printf("#include <desktop/tt_c.h>\n\n");
		printf("\tTt_pattern\ttt_pat;\n\n");

		printf("\ttt_open();\n\n");
	}

	/* Create a new pattern */
	if(tt_pat == NULL) /* first time only */
	{
		chkrc(tt_pointer_error(procid = tt_open()));
		fd = tt_fd();
		notify_set_input_func((Notify_client)set_pattern,
				      pat_receive,
				      fd);
	/* XXX - this init stuff (like when tt_open is done) should be reworked - dlarner */
		xv_set(ip->session_textfield, PANEL_VALUE, tt_default_session(), NULL);
	}
	else
	{
		tt_pattern_destroy(tt_pat);
	}

	chkrc(tt_ptr_error(tt_pat = tt_pattern_create()));
	if (trace_on) {
	        printf("\ttt_pat = tt_pattern_create();\n");
	}


	/* Setup pattern */

	/* Add address */
	setting = xv_get(ip->address_setting, PANEL_VALUE);
	for(i=0; i< 4; i++)
	{
		if(IF_SET(setting, i))
		{
			chkrc(tt_pattern_address_add(tt_pat, 
				address_name(xv_get(ip->address_setting, 
						    PANEL_CHOICE_STRING, i))));
			if (trace_on) {
	        		printf("\ttt_pattern_address_add(tt_pat, %s);\n",
				       xv_get(ip->address_setting, 
					      PANEL_CHOICE_STRING, i));
			}
		}
	}
	
	/* Add the objects to the pattern.  */
	buff = strdup((char *)xv_get(ip->object_textfield, PANEL_VALUE));
	   name = strtok(buff, ",");
	   while(name != (char *)NULL)
	    {
		while(*name == ' ') name++;
		c = &name[strlen(name) - 1];
		while(*c == ' ')
		{
			*c = '\0'; 
			c--;
		}
		chkrc(tt_pattern_object_add(tt_pat, name));
		if (trace_on) {
	        	printf("\ttt_pattern_object_add(tt_pat, \"%s\");\n",
			       name);
		}
		name = strtok(NULL, ",\n");
	    }
	   free(buff);
          

	/* Add the object type to the pattern. */
	buff = strdup((char *)xv_get(ip->otype_textfield, PANEL_VALUE));
	   name = strtok(buff, ",");
	   while(name != (char *)NULL)
	     {
		while(*name == ' ') name++;
		c = &name[strlen(name) - 1];
		while(*c == ' ')
		{
			*c = '\0'; 
			c--;
		}
		chkrc(tt_pattern_otype_add(tt_pat, name));
		if (trace_on) {
	        	printf("\ttt_pattern_otype_add(tt_pat, \"%s\");\n",
			       name);
		}
		name = strtok(NULL, ",\n");
	    }
	   free(buff);


	/* Add the operation.  Can be a list of comma seperated
	 * strings (i.e. launch, move)
	 */
	buff = strdup((char *)xv_get(ip->op_textfield, PANEL_VALUE));
	name = strtok(buff, ",");
	while(name != (char *)NULL)
	{
		while(*name == ' ') name++;
		c = &name[strlen(name) - 1];
		while(*c == ' ')
		{
			*c = '\0'; 
			c--;
		}
		chkrc(tt_pattern_op_add(tt_pat, name));
		if (trace_on) {
	        	printf("\ttt_pattern_op_add(tt_pat, \"%s\");\n",
			       name);
		}
		name = strtok(NULL, ",\n");
	}
	free(buff);

	/* Add the scope to the pattern. */
	setting = xv_get(ip->scope_setting, PANEL_VALUE);
	if (setting == 0) setting = 1;
	for(i=0; i < 4; i++)
	{
		if(IF_SET(setting, i))
		{
			chkrc(tt_pattern_scope_add(tt_pat, 
				scope_name(xv_get(ip->scope_setting, 
						  PANEL_CHOICE_STRING, i))));
			if (trace_on) {
	        		printf("\ttt_pattern_scope_add(tt_pat, %s);\n",
				       xv_get(ip->scope_setting, 
					      PANEL_CHOICE_STRING, i));
			}
		}
	}
	
	/* Add the session name to the pattern. */
/* currently only makes sense to add the default session to the pattern, but
since that's all we put in there as a read only field, proceed */ 
	buff = strdup((char *)xv_get(ip->session_textfield, PANEL_VALUE));

	name = strtok(buff, ",");
	while(name != (char *)NULL)
	{
		while(*name == ' ') name++;
		c = &name[strlen(name) - 1];
		while(*c == ' ')
		{
			*c = '\0'; 
			c--;
		}
		chkrc(tt_pattern_session_add(tt_pat, name));
		if (trace_on) {
	        	printf("\ttt_pattern_session_add(tt_pat, \"%s\");\n",
			       name);
		}
		name = strtok(NULL, ",\n");
	}

	free(buff);  
	

	/* Add the file names to the pattern */
	buff = strdup((char *)xv_get(ip->file_name_textfield, PANEL_VALUE));
	   name = strtok(buff, ",");
	   while(name != (char *)NULL)
	   {
		while(*name == ' ') name++;
		c = &name[strlen(name) - 1];
		while(*c == ' ')
		{
			*c = '\0'; 
			c--;
		}
		chkrc(tt_pattern_file_add(tt_pat, name));
		if (trace_on) {
	        	printf("\ttt_pattern_file_add(tt_pat, \"%s\");\n",
			       name);
		}
		file_names = str_arrayadd(file_names, name);
		name = strtok(NULL, ",\n");
	   }
	   free(buff);

	/*  For this version, the user won't be able to choose 
	 *  the category.  The default is TT_OBSERVE.
 	 */
        tt_pattern_category_set(tt_pat, TT_OBSERVE);
	if (trace_on) {
	        printf("\ttt_pattern_category_set(tt_pat, TT_OBSERVE);\n");
	}

	/* Add the class to the pattern. */
	setting = xv_get(ip->class_setting, PANEL_VALUE);
	for(i=0; i< 2; i++)
	{
		if(IF_SET(setting, i))
		{
			chkrc(tt_pattern_class_add(tt_pat, 
				class_name(xv_get(ip->class_setting, 
						  PANEL_CHOICE_STRING, i))));
			if (trace_on) {
	        		printf("\ttt_pattern_class_add(tt_pat, %s);\n",
				       xv_get(ip->class_setting, 
					      PANEL_CHOICE_STRING, i));
			}
		}
	}
	
	/* Add the disposition to the pattern. */
	setting = xv_get(ip->disposition_setting, PANEL_VALUE);
	for(i=0; i< 4; i++)
	{
		if(IF_SET(setting, i))
		{
			chkrc(tt_pattern_disposition_add(tt_pat, 
				disposition_name(xv_get(ip->disposition_setting,
							PANEL_CHOICE_STRING, i))));
			if (trace_on) {
	        		printf("\ttt_pattern_disposition_add(tt_pat, %s);\n",
				       xv_get(ip->disposition_setting, 
					      PANEL_CHOICE_STRING, i));
		       }
		}
	}
	

	/* Add the state to the pattern. */
	setting = xv_get(ip->state_setting, PANEL_VALUE);
	for(i=0; i< 7; i++)
	{
		if(IF_SET(setting, i))
		{
			chkrc(tt_pattern_state_add(tt_pat, 
				state_name(xv_get(ip->state_setting, 
						  PANEL_CHOICE_STRING, i))));
			if (trace_on) {
	        		printf("\ttt_pattern_state_add(tt_pat, %s);\n",
				       xv_get(ip->state_setting, 
					      PANEL_CHOICE_STRING, i));
		       }
		}
	}
	
	/* Add the sender to the pattern. */
	buff = strdup((char *)xv_get(ip->sender_textfield, PANEL_VALUE));
	name = strtok(buff, ",");
	while(name != (char *)NULL)
	{
		while(*name == ' ') name++;
		c = &name[strlen(name) - 1];
		while(*c == ' ')
		{
			*c = '\0'; 
			c--;
		}
		chkrc(tt_pattern_sender_add(tt_pat, name));
		if (trace_on) {
	        	printf("\ttt_pattern_sender_add(tt_pat, \"%s\");\n",
			       name);
		}
		name = strtok(NULL, ",\n");
	}
	free(buff);

	/* Add the sender_ptype to the pattern. */
	buff = strdup((char *)xv_get(ip->sender_ptype_textfield, PANEL_VALUE));
	name = strtok(buff, ",");
	while(name != (char *)NULL)
	{
		while(*name == ' ') name++;
		c = &name[strlen(name) - 1];
		while(*c == ' ')
		{
			*c = '\0'; 
			c--;
		}
		chkrc(tt_pattern_sender_ptype_add(tt_pat, name));
		if (trace_on) {
	        	printf("\ttt_pattern_sender_ptype_add(tt_pat, \"%s\");\n",
			       name);
		}
		name = strtok(NULL, ",\n");
	}
	free(buff);

	/* arguments */
        num = xv_get(ip->arg_list, PANEL_LIST_NROWS);
 
 	for(i = 0; i < num; i++)
	{
		arg = (Arg_list *)xv_get(ip->arg_list,
				PANEL_LIST_CLIENT_DATA, i);
		switch (arg->add_kind)
		  {
		  case BADD:   chkrc(tt_pattern_barg_add(tt_pat, arg->mode,
							 (const char *)arg->type,
	      (const unsigned char *)((strcmp(arg->value, "NULL") == 0) ? NULL : arg->value),
                                      (strcmp(arg->value, "NULL") == 0) ? NULL : strlen(arg->value)));
                            if (trace_on) {
                                printf((strcmp(arg->value, "NULL") == 0) ? 
				       "\ttt_pattern_barg_add(tt_pat, %s, \"%s\", %s, %d);\n" :
				       "\ttt_pattern_barg_add(tt_pat, %s, \"%s\", \"%s\", %d);\n",
                                       mode_val(arg->mode),
                                       arg->type,
				       arg->value,
                                       (strcmp(arg->value, "NULL") == 0) ? NULL : 
				                                   strlen(arg->value));
                             }	
                             break;
		  case IADD: chkrc(tt_pattern_iarg_add(tt_pat, arg->mode,
						       (const char *)arg->type,
		                       (strcmp(arg->value, "NULL") == 0) ? NULL : atoi(arg->value)));
			     if (trace_on) {
	        		    printf("\ttt_pattern_iarg_add(tt_pat, %s, \"%s\", %d);\n",
				       mode_val(arg->mode),
				       arg->type,
				       (strcmp(arg->value, "NULL") == 0) ? NULL : atoi(arg->value));
			         }
		             break;
		  case ADD:
                  default: chkrc(tt_pattern_arg_add(tt_pat, arg->mode,
						    (const char *)arg->type,
		       (const char *)((strcmp(arg->value, "NULL") == 0) ? NULL : arg->value)));
			     if (trace_on) {
	        		printf((strcmp(arg->value, "NULL") == 0) ? 
				       "\ttt_pattern_arg_add(tt_pat, %s, \"%s\", %s);\n" :
				       "\ttt_pattern_arg_add(tt_pat, %s, \"%s\", \"%s\");\n",
				       mode_val(arg->mode),
				       arg->type,
				       arg->value);
			      }
		              break; 
		  }
        }

	
	/* contexts */

        num = xv_get(Edit_receive_contexts_popup->receive_contexts_list,
		     PANEL_LIST_NROWS);

        for(i = 0; i < num; i++)
        {
                arg = (Arg_list *)xv_get(Edit_receive_contexts_popup->receive_contexts_list,
                                PANEL_LIST_CLIENT_DATA, i);
                switch (arg->add_kind)
		  {
		  case BADD: 
		         chkrc(tt_pattern_bcontext_add(tt_pat,
						       (const char *)arg->slotname, 
						       (const unsigned char *)((strcmp(arg->value, "NULL") == 0) ? NULL : arg->value),
						       (strcmp(arg->value, "NULL") == 0) ? NULL : strlen(arg->value)));
			 if (trace_on) {
			   printf((strcmp(arg->value, "NULL") == 0) ? 
				  "\ttt_pattern_bcontext_add(tt_pat, \"%s\", %s, %d);\n" :
				  "\ttt_pattern_bcontext_add(tt_pat, \"%s\", \"%s\", %d);\n",
				  arg->slotname,
				  arg->value, (strcmp(arg->value, "NULL") == 0) ? NULL : 
				                                   strlen(arg->value));
			 }
			 break;
		  case IADD: 
			chkrc(tt_pattern_icontext_add(tt_pat, arg->slotname, 
						      (strcmp(arg->value, "NULL") == 0) ? NULL : atoi(arg->value)));
			if (trace_on) {
	        		printf("\ttt_pattern_icontext_add(tt_pat, \"%s\", %d);\n",
				       arg->slotname,  (strcmp(arg->value, "NULL") == 0) ? NULL : atoi(arg->value));

			}
		        break;
		  case ADD:
                  default: 
			 chkrc(tt_pattern_context_add(tt_pat, arg->slotname, 
						      (const char *)((strcmp(arg->value, "NULL") == 0) ? NULL : arg->value)));

			if (trace_on) {
	        		printf((strcmp(arg->value, "NULL") == 0) ? 
				       "\ttt_pattern_context_add(tt_pat, \"%s\", %s);\n" :
				       "\ttt_pattern_context_add(tt_pat, \"%s\", \"%s\");\n",
				       arg->slotname,
				       (const char *)((strcmp(arg->value, "NULL") == 0) ? NULL : arg->value));
			}

		  }
               
	}	/* end -for (all contexts) - */

	/* register pattern */
	chkrc(tt_pattern_register(tt_pat));
	if (trace_on) {
	        printf("\ttt_pattern_register(tt_pat);\n");
	}
/* XXX - Note it's not really necessary to join the files since the filename
   was already on the pattern when it was registered - dlarner */
/*	if (((scope_value == 2) || (scope_value == 4)) && 
            (file_names != (char **)NULL)) {
		i = 0;
		while (file_names[i]) {
	  		chkrc(tt_file_join(file_names[i]));
	  		if (trace_on) {
	          		printf("\ttt_file_join(\"%s\");\n", file_names[i]);
	  		}
			free(file_names[i]);
	  		i++;
		}
                free(file_names);
	}
*/
        
}
