/* 
 * send_message.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 "send_ui.h"
#include "arg_edit.h"
#include "ttsnoop.h"

Arg_list *	get_arg();
Arg_list *	put_arg();
char     *	label_arg();

Msg_list *	put_message();
Msg_list *	get_message();
char     *	label_message();

send_send_msg_popup_objects	*ip = 0;

char	*procid;

extern int	trace_on;

send_init(send_send_msg_popup_objects *ip_tmp)
{
	ip = ip_tmp;

	init_lst(ip->arg_list,
		ip->add_button,
		ip->delete_button,
		ip->change_button,
		NULL,
		get_arg,
		put_arg,
		label_arg);

	init_lst(ip->message_list,
		ip->add_message_button,
		ip->delete_message_button,
		ip->change_message_button,
		NULL,
		get_message,
		put_message,
		label_message);

	xv_set(ip->session_textfield,
			PANEL_VALUE,	tt_default_session(),
			NULL);
	xv_set(ip->sender_ptype_textfield,
			PANEL_VALUE,	tt_default_ptype(),
			NULL);
}

/* send_message() - send the message based on the settings selected
 *		    in the Xview panel.
 */
send_message(send_send_msg_popup_objects *ip_tmp)
{
	static  Tt_message      tt_msg = NULL;
	Tt_address	address;
	Tt_class	class;
	Tt_scope	scope;
	char		*value;
	int		num;
	Arg_list	*arg;
	int		i;

	chkrc(tt_ptr_error(tt_msg = tt_message_create()));
	if (trace_on) {
		printf("\n--------------- Message Code -------------------------\n");
		printf("#include <desktop/tt_c.h>\n\n");
		printf("\tTt_message	tt_msg;\n\n");
		printf("\ttt_open();\n\n");
		printf("\ttt_msg = tt_message_create();\n");
	}


	/* setup message */

	/* Address is required */
	value = (char *)xv_get(ip->address_setting, PANEL_CHOICE_STRING,
		xv_get(ip->address_setting, PANEL_VALUE));
	chkrc(tt_message_address_set(tt_msg, address = address_name(value)));
	if (trace_on) {
		printf("\ttt_message_address_set(tt_msg, %s);\n", value);
	}

	/* class is required */
	value = (char *)xv_get(ip->class_setting, PANEL_CHOICE_STRING,
		xv_get(ip->class_setting, PANEL_VALUE));
	chkrc(tt_message_class_set(tt_msg, class = class_name(value)));
	if (trace_on) {
	        printf("\ttt_message_class_set(tt_msg, %s);\n", value);
        }

	/* scope */
	value = (char *)xv_get(ip->scope_setting,
			       PANEL_CHOICE_STRING,
		               xv_get(ip->scope_setting, PANEL_VALUE));
	chkrc(tt_message_scope_set(tt_msg, scope = scope_name(value)));
	if (trace_on) {
	        printf("\ttt_message_scope_set(tt_msg, %s);\n", value);
        }

	value = (char *)xv_get(ip->file_name_textfield, PANEL_VALUE);
	if(value && strlen(value))
	{
		chkrc(tt_message_file_set(tt_msg, value));
		if (trace_on) {
		        printf("\ttt_message_file_set(tt_msg, \"%s\");\n",
			       value);
	        }
	}

	value = (char *)xv_get(ip->session_textfield, PANEL_VALUE);
	if (!value || !strlen(value)) {
		if ((scope == TT_SESSION) || (scope == TT_FILE_IN_SESSION)) {
			chkrc(tt_message_session_set(tt_msg, tt_default_session()));
			if (trace_on) {
	        		printf("\ttt_message_session_set(tt_msg, tt_default_session());\n");
			}
		}
	}
	else if (value) {
		chkrc(tt_message_session_set(tt_msg, value));
		if (trace_on) {
	        	printf("\ttt_message_session_set(tt_msg, \"%s\");\n",
			       value);
		}
	}

	/* object */
	value = (char *)xv_get(ip->object_textfield, PANEL_VALUE);
	if(value && strlen(value))
	{
		chkrc(tt_message_object_set(tt_msg, value));
		if (trace_on) {
		        printf("\ttt_message_object_set(tt_msg, \"%s\");\n",
			       value);
	        }
	}

	/* op */
	if(*(value = (char *)xv_get(ip->op_textfield, PANEL_VALUE)))
	{
		chkrc(tt_message_op_set(tt_msg, value));
		if (trace_on) {
		        printf("\ttt_message_op_set(tt_msg, \"%s\");\n",
			       value);
	        }
	}


	/* otype */
	value = (char *)xv_get(ip->otype_textfield, PANEL_VALUE);
	if(value && strlen(value))
	{
		chkrc(tt_message_otype_set(tt_msg, value));
		if (trace_on) {
		        printf("\ttt_message_otype_set(tt_msg, \"%s\");\n",
			       value);
	        }
	}


	/* handler */
	value = (char *)xv_get(ip->handler_textfield, PANEL_VALUE);
	if(value && strlen(value))
	{
		chkrc(tt_message_handler_set(tt_msg, value));
		if (trace_on) {
		        printf("\ttt_message_handler_set(tt_msg, \"%s\");\n",
			       value);
	        }
	}


	/* handler type */
	if(*(value = (char *)xv_get(ip->handler_ptype_textfield, PANEL_VALUE)))
	{
		chkrc(tt_message_handler_ptype_set(tt_msg, value));
		if (trace_on) {
		        printf("\ttt_message_handler_ptype_set(tt_msg, \"%s\");\n",
			       value);
		}

	}

	/* disposition */
	value = (char *)xv_get(ip->disposition_setting, PANEL_CHOICE_STRING,
		xv_get(ip->disposition_setting, PANEL_VALUE));
	chkrc(tt_message_disposition_set(tt_msg, 
				disposition_name(value)));
	if (trace_on) {
	        printf("\ttt_message_disposition_set(tt_msg, %s);\n", value);
	}

	/* sender ptype */
	if(*(value = (char *)xv_get(ip->sender_ptype_textfield,	PANEL_VALUE)))
	{
		chkrc(tt_message_sender_ptype_set(tt_msg, value));
		if (trace_on) {
	        	printf("\ttt_message_sender_ptype_set(tt_msg, \"%s\");\n",
			       value);
		}
	}


	/* Add any specified 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_message_barg_add(tt_msg, 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_message_barg_add(tt_msg, %s, \"%s\", %s, %d);\n" :
				       "\ttt_message_barg_add(tt_msg, %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_message_iarg_add(tt_msg, arg->mode,
						       (const char *)arg->type,
		                  (strcmp(arg->value, "NULL") == 0) ? NULL : atoi(arg->value)));
			     if (trace_on) {
	        		    printf("\ttt_message_iarg_add(tt_msg, %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_message_arg_add(tt_msg, 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_message_arg_add(tt_msg, %s, \"%s\", %s);\n" :
				       "\ttt_message_arg_add(tt_msg, %s, \"%s\", \"%s\");\n",
				       mode_val(arg->mode),
				       arg->type,
				       arg->value);
			      }
		              break; 
		  }

	}


	/* Add contexts, aka. keyword paramaters */
	num = xv_get(Edit_send_contexts_popup->send_contexts_list,
		     PANEL_LIST_NROWS);

	for(i = 0; i < num; i++)
        {
		arg = (Arg_list *)xv_get(Edit_send_contexts_popup->send_contexts_list,
				PANEL_LIST_CLIENT_DATA, i);

                switch (arg->add_kind)
		  {
		  case BADD: 
		         chkrc(tt_message_bcontext_set(tt_msg,
						       (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_message_bcontext_set(tt_msg, \"%s\", %s, %d);\n" :
				  "\ttt_message_bcontext_set(tt_msg, \"%s\", \"%s\", %d);\n",
				  arg->slotname,
				  arg->value, (strcmp(arg->value, "NULL") == 0) ? NULL : 
				                                   strlen(arg->value));
			 }
			 break;
		  case IADD: 
			chkrc(tt_message_icontext_set(tt_msg, arg->slotname, 
						      (strcmp(arg->value, "NULL") == 0) ? NULL : atoi(arg->value)));
			if (trace_on) {
	        		printf("\ttt_message_icontext_set(tt_msg, \"%s\", %d);\n",
				       arg->slotname,  (strcmp(arg->value, "NULL") == 0) ? NULL : atoi(arg->value));

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

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

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

	chkrc(tt_message_scope_set(tt_msg,scope));
	if (trace_on) {
	        printf("\ttt_message_scope_set(tt_msg, %s);\n",
		       scope_val(scope));
	}

	chkrc(tt_message_send(tt_msg));
	if (trace_on) {
	        printf("\ttt_message_send(tt_msg);\n");
	}

	chkrc(tt_message_destroy(tt_msg));
}

Arg_list *
get_arg(Arg_list *item)
{
	if(item == NULL)
	{
		item = (Arg_list *)malloc(sizeof(Arg_list));
		memset((void *)item, '\0', sizeof(Arg_list));
	}
	ENUM_GET(ip, mode_setting, mode);
	ENUM_GET(ip, kind_of_add, add_kind);
	CHAR_GET(ip, type_textfield, type);
	CHAR_GET(ip, value_textfield, value);


	return(item);
}

Arg_list *
put_arg(Arg_list *item)
{
	ENUM_SET(ip, mode_setting, mode, 1, -1);
	ENUM_SET(ip, kind_of_add, add_kind, 0, 0);

	CHAR_SET(ip, type_textfield, type);
	CHAR_SET(ip, value_textfield, value);
}


char *
label_arg(Arg_list *item)
{
	static	char	buffer[1024];

	        sprintf(buffer, "%s %s(mode) %s(type) %s(value)\0",
		add_kind_val(item->add_kind),
		mode_val(item->mode),
		item->type,
		item->value);
	return(buffer);
}

Arg_list **
dup_arglist(Arg_list **arglist)
{
	int		count;
	int		i;
	Arg_list	**out;

	count = 0;

	while(arglist[count] != 0)
	{
		count++;
	}

	out = (Arg_list **)malloc((count+1)*sizeof(Arg_list *));
	memset((void *)out, '\0', (count+1)*sizeof(Arg_list *));

	for(i = 0; i < count; i++)
	{
		out[i] = (Arg_list *)malloc(sizeof(Arg_list));
		memcpy((void *)out[i], (void *)arglist[i], sizeof(Arg_list));
	}
	out[i] = (Arg_list *)NULL;

	return(out);
}

free_arglist(Arg_list **arglist)
{
	int		count;
	Arg_list	**out;

	count = 0;
	while(arglist[count])
	{
		free(arglist[count]);
		count++;
	}
	free(arglist);
}

print_arglist(Arg_list **arglist)
{
	int		count;
	Arg_list	**out;

	count = 0;
	if (trace_on) {
	        printf("List address = %x\n", arglist);
	}
	while(arglist[count])
	{
	        if (trace_on) {
	        	printf("%x\t%s\n",
			       arglist[count],
			       label_arg(arglist[count]));
		}
		count++;
	}
}

print_msglist()
{
	int		count = xv_get(ip->message_list, PANEL_LIST_NROWS);
	Msg_list	*msg;
	int		i;

	for(i = 0; i < count; i++)
	{
		msg = (Msg_list*)xv_get(ip->message_list, 
				PANEL_LIST_CLIENT_DATA, i);
		if (trace_on) {
	        	printf("Msg address (%s)= %x\n  Arg list:",
			       msg->label, msg);
		}
		print_arglist(msg->list);
	}
}

char *
label_message(Msg_list *item)
{
	return(item->label);
}

/* XXX DLL the next two functions very crudely use Edit_send_contexts_popup - this program
was not originally designed with contexts in mind, and the way they were added later
separates the context from the message too much. Overall, the whole of ttsnoop should
be reorganized/redesigned, but since it's still classed as a 'Demo' ...  */

Msg_list *
put_message(Msg_list *item)  /* set display to the message */
{
	int		i, n;

	ENUM_SET(ip, address_setting, address, 0, 0);
	ENUM_SET(ip, class_setting, class, 1, -1);
	ENUM_SET(ip, scope_setting, scope, 1, -1);
	CHAR_SET(ip, session_textfield, session);
	CHAR_SET(ip, file_name_textfield, file);
	CHAR_SET(ip, object_textfield, object);
	CHAR_SET(ip, op_textfield, op);
	CHAR_SET(ip, otype_textfield, otype);
	CHAR_SET(ip, handler_textfield, handler);
	CHAR_SET(ip, handler_ptype_textfield, handler_ptype);
	ENUM_SET(ip, disposition_setting, disposition, 0, 0);
	CHAR_SET(ip, sender_ptype_textfield, sender_ptype);
	CHAR_SET(ip, label_textfield, label);
	if(item == NULL)
	{
		set_list(ip->arg_list, NULL);
		set_list(Edit_send_contexts_popup->send_contexts_list, NULL);
	}
	else
	{
		set_list(ip->arg_list, dup_arglist(item->list));
		set_list(Edit_send_contexts_popup->send_contexts_list, dup_arglist(item->cntxtlist));
	}
}

Msg_list *
get_message(Msg_list *item) /* set message to the display */
{
	int		i = 0;
	int		new = FALSE;

	if(item == NULL)
	{
		new = TRUE;
		item = (Msg_list *)malloc(sizeof(Msg_list));
		memset((void *)item, '\0', sizeof(Msg_list));
	}

	ENUM_GET(ip, address_setting, address);
	ENUM_GET(ip, class_setting, class);
	ENUM_GET(ip, scope_setting, scope);
	CHAR_GET(ip, session_textfield, session);
	CHAR_GET(ip, file_name_textfield, file);
	CHAR_GET(ip, object_textfield, object);
	CHAR_GET(ip, op_textfield, op);
	CHAR_GET(ip, otype_textfield, otype);
	CHAR_GET(ip, handler_textfield, handler);
	CHAR_GET(ip, handler_ptype_textfield, handler_ptype);
	ENUM_GET(ip, disposition_setting, disposition);
	CHAR_GET(ip, sender_ptype_textfield, sender_ptype);
	CHAR_GET(ip, label_textfield, label);

	if(!new)
	{
		free_arglist(item->list);
		free_arglist(item->cntxtlist);
	}

	item->list = dup_arglist((Arg_list **)get_list(ip->arg_list));
	item->cntxtlist = dup_arglist((Arg_list **)get_list(Edit_send_contexts_popup->send_contexts_list));


	set_list(ip->arg_list, NULL); 
	set_list(Edit_send_contexts_popup->send_contexts_list, NULL); 
	item->arg_count = 0;
	while(item->list[item->arg_count] != 0)
	{
		item->arg_count++;
	}

	
	return(item);
}
