#include <string.h>
#include <assert.h>
#include <memory.h>

#include "darray.h"
#include "action.h"
#include "data.h"
#include "rule.h"
#include "ruleP.h"
#include "MsgType.h"
#include "MTreg.h"
#include "verbrgy.h"
#include "rap.h"

AlRule
AlRule_create(predicate, actions, created, updated, name)
AlRuleMember	predicate;
Darray		actions;
time_t		created,
		updated;
char		*name;
{
	AlRule	rule;

	assert(predicate);
 	assert(actions);
	
	rule = (AlRule)Memory_allocate(sizeof(AlRuleSt));
	rule->predicate = predicate;
	rule->actions = actions;
	rule->state = (r_state)0;
	if(name != (char *)NULL)
	{	rule->name = (char *)Memory_allocate(strlen(name) + 1);
		strcpy(rule->name, name);
	}
	else
		rule->name = (char *)NULL;
	if(created)
	{	rule->creation = created;
		rule->update = updated;
	}
	else
	{	rule->update = time(&rule->creation);
		SET(rule->state, RST_NEW);
		AlData_rule_created(rule);
	}

	return rule;
}

AlRule
AlRule_copy(rule)
AlRule	rule;
{
	Darray		actions;
	unsigned int	i,
			len;

	assert(rule !=  (AlRule)NULL);

	actions = Darray_create();
	Darray_hint(actions, (unsigned)0, len = Darray_len(rule->actions));
	for(i = 0; i < len; i++)
		Darray_addh(actions, 
			    (VOIDP)AlAction_copy((AlAction)
						Darray_get(rule->actions, i)));
	return AlRule_create(AlRuleMember_copy(rule->predicate), actions,
			     rule->creation, rule->update, rule->name);
}

NORET
AlRule_destroy(rule)
AlRule	rule;
{
	unsigned	len,
			i = 0;
	
	assert(rule);
	for(len = Darray_len(rule->actions); i < len; i++)
		AlAction_destroy((AlAction)Darray_get(rule->actions, i));
	Darray_destroy(rule->actions);
	AlRuleMember_destroy(rule->predicate);
	AlData_rule_deleted(rule);
	if(rule->name)
		Memory_free((VOIDP)rule->name);
	Memory_free((VOIDP)rule);
}

Darray
AlRule_get_actions(rule)
AlRule	rule;
{
	assert(rule);
	return rule->actions;
}

time_t
AlRule_get_creation(rule)
AlRule	rule;
{
	assert(rule);
	return rule->creation;
}

time_t
AlRule_get_update(rule)
AlRule	rule;
{
	assert(rule);
	return rule->update;
}

char *
AlRule_get_name(rule)
AlRule	rule;
{
	assert(rule);
	return rule->name;
}

char *
AlRule_set_name(rule, name)
AlRule	rule;
char	*name;
{
	assert(rule);

	if(rule->name)
		Memory_free((VOIDP)rule->name);
	rule->name = (char *)Memory_allocate(strlen(name) + 1);
	return strcpy(rule->name, name);
}

NORET
AlRule_mark_changed(rule)
AlRule	rule;
{
	time_t	t;

	assert(rule);
	SET(rule->state, RST_CHG);
	t = rule->update;
	time(&rule->update);
	AlData_rule_changed(rule, t);
}

NORET
AlRule_mark_unchanged(rule)
AlRule	rule;
{
	assert(rule);
	UNSET(rule->state, RST_CHG);
}

AlRuleMember
AlRule_get_predicate(rule)
AlRule	rule;
{
	assert(rule);
	return rule->predicate;
}

AlRuleMember
AlRuleMember_mcreate_assoc(type)
AlRAType	type;
{
	AlRuleMember	rm;

	rm = (AlRuleMember)Memory_allocate(sizeof(AlRuleMemberSt));
	rm->m_kind = ALRMT_ASSOC;
	rm->type.assoc = (AlRuleAssoc)Memory_allocate(sizeof(AlRuleAssocSt));
	rm->type.assoc->a_type = type;
	rm->container = (AlRuleAssoc)NULL;
	rm->type.assoc->contents = rm->sibling = rm->previous = 
	  (AlRuleMember)NULL;
	rm->type.assoc->as_member = rm;

	return rm;
}

AlRuleMember
AlRuleMember_mcreate_field(kind, key, type, value, op)
AlRFType	kind;
char		*key,
		*type,
		*value,
		*op;
{
	AlRuleMember	rm;

	rm = (AlRuleMember)Memory_allocate(sizeof(AlRuleMemberSt));
	rm->m_kind = ALRMT_FIELD;
	rm->type.field = (AlRuleField)Memory_allocate(sizeof(AlRuleFieldSt));
	rm->type.field->f_type = kind;	
	rm->type.field->value = (char *)Memory_allocate(strlen(value) + 1);
	strcpy(rm->type.field->value, value);
	rm->type.field->op_name = (char *)Memory_allocate(strlen(op) + 1);
	strcpy(rm->type.field->op_name, op);
	rm->type.field->fc = AlFieldCore_create(type);
	AlFieldCore_set_key(rm->type.field->fc, key);
	if(AlFieldCore_parse(rm->type.field->fc, value) == Bool_FALSE)
		/* set errcode !!!! */
		return (AlRuleMember)NULL;
	rm->type.field->op_func = AlFieldType_get_field_op_proc(
				 	AlFieldCore_get_field_type(rm->type.field->fc),
					op);
	rm->type.field->as_member = rm;
	rm->container = (AlRuleAssoc)NULL;
	rm->sibling  = (AlRuleMember)NULL;
	rm->previous  = (AlRuleMember)NULL;

	return rm;
}


/* This function allows the creatrion of a field when the field type will */
 /* not parse the value of the field with the current operator.  In this */
 /* case the actual operator function is set to NULL to tell runrules not to */
 /* fire this field. */
AlRuleMember
AlRuleMember_mcreate_field_no_parse(kind, key, type, value, op)
AlRFType	kind;
char		*key,
		*type,
		*value,
		*op;
{
	AlRuleMember	rm;

	rm = (AlRuleMember)Memory_allocate(sizeof(AlRuleMemberSt));
	rm->m_kind = ALRMT_FIELD;
	rm->type.field = (AlRuleField)Memory_allocate(sizeof(AlRuleFieldSt));
	rm->type.field->f_type = kind;	
	rm->type.field->value = (char *)Memory_allocate(strlen(value) + 1);
	strcpy(rm->type.field->value, value);
	rm->type.field->op_name = (char *)Memory_allocate(2);
	strcpy(rm->type.field->op_name, "");
	rm->type.field->fc = AlFieldCore_create(type);
	AlFieldCore_set_key(rm->type.field->fc, key);
	if(AlFieldCore_parse(rm->type.field->fc, value) == Bool_FALSE)
	  rm->type.field->op_func = NULL;
	else
	  rm->type.field->op_func = 
	    AlFieldType_get_field_op_proc(
					  AlFieldCore_get_field_type(rm->type.field->fc),
					  op);
	rm->type.field->as_member = rm;
	rm->container = (AlRuleAssoc)NULL;
	rm->sibling  = (AlRuleMember)NULL;
	rm->previous  = (AlRuleMember)NULL;

	return rm;
}


Bool
AlRuleField_test_contents(field)
AlRuleField field;
{
	if(AlFieldCore_parse(field->fc,field->value) == Bool_FALSE)
             /* set errcode !!!! */
        	return Bool_FALSE;
	else
		return Bool_TRUE;
}


AlRuleMember
AlRuleMember_copy(rm)
AlRuleMember	rm;
{
	AlRuleMember	new_rm;
	AlRuleField	rf;
	AlRuleAssoc	ra,
			new_ra;
	Darray		contents;
	unsigned int	len;

	assert(rm != (AlRuleMember)NULL);

	if(rm->m_kind == ALRMT_FIELD)
	{	rf = rm->type.field;
		new_rm = AlRuleMember_mcreate_field(rf->f_type, 
				AlFieldCore_get_key(rf->fc),
				AlFieldCore_get_field_type_name(rf->fc),
				rf->value, rf->op_name);
		return new_rm;
	}
	ra = rm->type.assoc;
	new_rm = AlRuleMember_mcreate_assoc(ra->a_type);
	new_ra = new_rm->type.assoc;
	contents = Darray_create();
	AlRuleAssoc_get_contents(ra, contents);
	len = Darray_len(contents);
	while(len--)
		AlRuleAssoc_make_member_of(new_ra, AlRuleMember_copy((AlRuleMember)
					     	     Darray_reml(contents)));
	Darray_destroy(contents);
	return new_rm;
}

						    
	

NORET
AlRuleMember_destroy(rm)
AlRuleMember	rm;
{
	assert(rm);
	if(rm->m_kind == ALRMT_ASSOC)
		destroy_assoc(rm->type.assoc);
	else
		destroy_field(rm->type.field);
	Memory_free((VOIDP)rm);
}

destroy_assoc(assoc)
AlRuleAssoc	assoc;
{
	Darray	contents = Darray_create();
	unsigned	i = 0,
			len;

	AlRuleAssoc_get_contents(assoc, contents);
	for(len = Darray_len(contents); i < len; i++)
		AlRuleMember_destroy((AlRuleMember)Darray_get(contents, i));
	Darray_destroy(contents);
	Memory_free((VOIDP)assoc);
}

destroy_field(field)
AlRuleField	field;
{
	assert(field);
	Memory_free((VOIDP)field->value);
	Memory_free((VOIDP)field->op_name);
	AlFieldCore_delete(field->fc);
	Memory_free((VOIDP)field);
}

NORET
AlRuleMember_insert_after(after_here, member)
AlRuleMember	after_here,
		member;
{
        member->previous = after_here;
	member->sibling = after_here->sibling;
	after_here->sibling = member;
	if (member->sibling!=NULL)
	  member->sibling->previous = member;
	member->container = after_here->container;
}


NORET	/* Maybe should return something (like the member before it) ? */
AlRuleAssoc_make_member_of(assoc, member)
AlRuleAssoc	assoc;
AlRuleMember	member;
{
	AlRuleMember	mtmp;

	if(!assoc->contents)
	{	assoc->contents = member;
		member->container = assoc;
		return;
	}
	for(mtmp = assoc->contents; mtmp->sibling; mtmp = mtmp->sibling)
			;
	mtmp->sibling = member;
	member->container = mtmp->container;
	member->previous = mtmp;
	/* Might want to add something in reverse */
}

AlRuleMember
AlRuleAssoc_as_member(assoc)
AlRuleAssoc	assoc;
{
	assert(assoc);
	return assoc->as_member;
}

AlRuleAssoc
AlRuleMember_remove(member)
AlRuleMember	member;
{
	AlRuleMember	mtmp;
	AlRuleAssoc	assoc;

	if((assoc = member->container) == NULL)
		return (AlRuleAssoc)NULL;	/* top level assoc */
	if((mtmp = assoc->contents) == member)
	{	assoc->contents = member->sibling;
		if (member->sibling!=NULL)
		  member->sibling->previous = NULL;
		member->container = (AlRuleAssoc)NULL;
		return assoc;
	}
	else for(; mtmp->sibling != member; mtmp = mtmp->sibling)
		;
	mtmp->sibling = member->sibling;
	if (member->sibling!=NULL)
	  member->sibling->previous=mtmp;
	member->sibling = (AlRuleMember)NULL;
	member->previous = (AlRuleMember)NULL;
	member->container = (AlRuleAssoc)NULL;
	return assoc;
}

AlRMType
AlRuleMember_get_type(member)
AlRuleMember	member;
{
	assert(member);
	return	member->m_kind;
}

AlRAType
AlRuleAssoc_get_type(assoc)
AlRuleAssoc	assoc;
{
	assert(assoc);
	return assoc->a_type;
}

const char *
AlRuleAssoc_atype(at)
AlRAType	at;
{
	switch(at) {
	case ALRAT_AND:
		return "and";
	case ALRAT_OR:
		return "or";
	case ALRAT_NOT:
		return "not";
	}
}

AlRFType
AlRuleField_get_type(field)
AlRuleField	field;
{
	assert(field);
	return field->f_type;
}

NORET
AlRuleField_set_key(field, key)
AlRuleField	field;
char		*key;
{
	assert(field);

	AlFieldCore_set_key(field->fc, key);
}

Bool
AlRuleField_set_value(field, value)
AlRuleField	field;
char		*value;
{
	assert(field);

	Memory_free((VOIDP)field->value);
	field->value = (char *)Memory_allocate(strlen(value) + 1);
	strcpy(field->value, value);
	return AlFieldCore_parse(field->fc, field->value);
}

Bool
AlRuleField_set_type(field, type)
AlRuleField	field;
char		*type;
{
	assert(field);

	AlFieldCore_set_field_type(field->fc, AlFieldType_get_field_type(type));
	return AlFieldCore_parse(field->fc, field->value);
}

Bool
AlRuleField_set_op(field, op)
AlRuleField	field;
char		*op;
{
	assert(field);

	Memory_free((VOIDP)field->op_name);
	field->op_name = (char *)Memory_allocate(strlen(op) + 1);
	field->op_func = AlFieldType_get_field_op_proc(
				 	AlFieldCore_get_field_type(field->fc),
					strcpy(field->op_name, op));
	return AlFieldCore_parse(field->fc, field->value);
}

AlRuleMember
AlRuleField_as_member(field)
AlRuleField	field;
{
	assert(field);
	return field->as_member;
}

AlRuleAssoc
AlRuleMember_get_assoc(member)
AlRuleMember	member;
{
	assert(member);
	assert(member->m_kind == ALRMT_ASSOC);
	return member->type.assoc;
}

AlRuleField
AlRuleMember_get_field(member)
AlRuleMember	member;
{
	assert(member);
	assert(member->m_kind == ALRMT_FIELD);
	return member->type.field;
}

/* I don't  think this is really what you want ... !!! */
Darray
AlRuleAssoc_get_contents(assoc, contents)
AlRuleAssoc	assoc;
Darray		contents;
{
	AlRuleMember	mtmp;

	for(mtmp = assoc->contents; mtmp; mtmp = mtmp->sibling)
		Darray_addh(contents, (VOIDP)mtmp);

	return contents;
}

AlRuleMember
AlRuleMember_get_sibling(member)
AlRuleMember	member;
{
	assert(member);
	return member->sibling;
}

AlRuleMember
AlRuleMember_get_previous(member)
AlRuleMember	member;
{
	assert(member);
	return member->previous;
}

AlRuleMember
AlRuleAssoc_get_first_member(assoc)
AlRuleAssoc	assoc;
{
	assert(assoc);
	return assoc->contents;
}

AlFieldCore
AlRuleField_get_fc(field)
AlRuleField	field;
{
	assert(field);
	return field->fc;
}

char *
AlRuleField_get_strvalue(field)
AlRuleField	field;
{
	assert(field);
	return field->value;
}

char *
AlRuleField_get_op_name(field)
AlRuleField	field;
{
	assert(field);
	return field->op_name;
}

FieldOperatorProc *
AlRuleField_get_op_func(field)
AlRuleField	field;
{
	assert(field);
	return field->op_func;
}

AlRuleAssoc
AlRuleMember_get_container(member)
AlRuleMember member;
{
  return(member->container);
}


/*--------------------------------------------------*/
Bool AlRule_is_state(ft)
AlRFType ft;
{
  return(Bool_create((ft == ALRFT_SMF) ||
		     (ft == ALRFT_SNTM) ||
		     (ft == ALRFT_SNRF) ||
		     (ft == ALRFT_SNOF) ||
		     (ft == ALRFT_SMLL) ||
		     (ft == ALRFT_SMCL) ||
		     (ft == ALRFT_SBLL) ||
		     (ft == ALRFT_SBCL) ||
		     (ft == ALRFT_SNUB) ||
		     (ft == ALRFT_SFC) ) );
}

/*--------------------------------------------------*/
Bool AlRule_is_processing_state(ft)
AlRFType ft;
{
  return(Bool_create((ft == ALRFT_SMF) ||
		     (ft == ALRFT_SNTM) ||
		     (ft == ALRFT_SNRF) ));
}


/*--------------------------------------------------*/
Bool AlRule_is_message_property(ft)
AlRFType ft;
{
  return(Bool_create((ft == ALRFT_SNOF) ||
		     (ft == ALRFT_SMLL) ||
		     (ft == ALRFT_SMCL) ||
		     (ft == ALRFT_SBLL) ||
		     (ft == ALRFT_SBCL) ||
		     (ft == ALRFT_SNUB) ||
		     (ft == ALRFT_SFC) ) );
}

#define USER_PROPERTY    "User Property"
#define MAILER_INTERFACE "Mailer Interface"

#define  MOVED_FROM "Moved From"
#define  N_OF_TIMES_MOVED  "Number of Times Moved"
#define  N_OF_RULES_FIRED_ON_MESSAGE  "Number of Rules Fired On Message"
#define  N_OF_FIELDS_IN_MESSAGE  "Number of Fields in Message"
#define  N_OF_LINES_IN_MESSAGE  "Number of Lines in Message"
#define  N_OF_CHARACTERS_IN_MESSAGE  "Number of Characters in Message"
#define  N_OF_LINES_IN_BODY  "Number of Lines in Body"
#define  N_OF_CHARACTERS_IN_BODY  "Number of Characters in Body"
#define  UNPRINTABLES_IN_BODY  "Unprintables in Body"

static char *FieldClass_strings[]={
  "Message",
  USER_PROPERTY,
  MAILER_INTERFACE,
/*  "Processing State",
  "Message Properties", */
  NULL,
};

static char *ProcessingState_strings[]={
  MOVED_FROM,
  N_OF_TIMES_MOVED,
  N_OF_RULES_FIRED_ON_MESSAGE,
  NULL,
};

static char *MessageProperty_strings[]={
  N_OF_FIELDS_IN_MESSAGE,
  N_OF_LINES_IN_MESSAGE,
  N_OF_CHARACTERS_IN_MESSAGE,
  N_OF_LINES_IN_BODY,
  N_OF_CHARACTERS_IN_BODY,
  UNPRINTABLES_IN_BODY,
  /*  "Field Count", */
  NULL,
};

typedef struct relation11_str {
  AlRFType     class;
  char*    name;
  char*    fieldType;
} *relation11;

static struct relation11_str FieldClassFieldTypes[]={
  { ALRFT_MSG,   "Message", NULL, },
  { ALRFT_UP,    USER_PROPERTY, NULL, },
  { ALRFT_FI,    MAILER_INTERFACE, NULL },
  { ALRFT_SMF,   MOVED_FROM, "Case Sensitive Text", },
  { ALRFT_SNTM,  N_OF_TIMES_MOVED, "Integer", },
  { ALRFT_SNRF,  N_OF_RULES_FIRED_ON_MESSAGE, "Integer", },
  { ALRFT_SNOF,  N_OF_FIELDS_IN_MESSAGE, "Integer", },
  { ALRFT_SMLL,  N_OF_LINES_IN_MESSAGE, "Integer", },
  { ALRFT_SMCL,  N_OF_CHARACTERS_IN_MESSAGE, "Integer", },
  { ALRFT_SBLL,  N_OF_LINES_IN_BODY, "Integer", },
  { ALRFT_SBCL,  N_OF_CHARACTERS_IN_BODY, "Integer", },
  { ALRFT_SNUB,  UNPRINTABLES_IN_BODY, "Boolean", },
/* { ALRFT_SFC,   "field count", "Integer", }, */
  { NULL, NULL, NULL },
};

/*--------------------------------------------------*/
NORET AlRule_get_field_class_names(d)
Darray d;
{
  char* s;
  int i=0;
  while ((s=FieldClass_strings[i])!=NULL)
    Darray_addh(d,FieldClass_strings[i++]);
}

/*--------------------------------------------------*/
NORET AlRule_get_processing_state_names(d)
Darray d;
{
  char* s;
  int i=0;
  while ((s=ProcessingState_strings[i])!=NULL)
    Darray_addh(d,ProcessingState_strings[i++]);
}

/*--------------------------------------------------*/
NORET AlRule_get_message_property_names(d)
Darray d;
{
  char* s;
  int i=0;
  while ((s=MessageProperty_strings[i])!=NULL)
    Darray_addh(d,MessageProperty_strings[i++]);
}

/*--------------------------------------------------*/
/* will return NULL if there is no default field type for a given field */
 /* class (i.e. if you call this funtion with one of the 5 proper field */
 /* classes */
/*----------------------------------------*/
char* AlRule_get_field_class_default_field_type(fc)
     AlRFType fc;
{
  int i;
  relation11 r;
  i=0;
  r=&(FieldClassFieldTypes[i]);
  while (r->name!=NULL) {
    if (r->class==fc)
      return(r->fieldType);
    r=&(FieldClassFieldTypes[++i]);    
  }
  Al_fatal_error("AlRule_get_field_class_default_field_type: passed bad field class\n");
  return((char*)NULL); /* for compilers */
}

/*--------------------------------------------------*/
AlRFType AlRule_get_class_from_name(n)
     char *n;
{
  int i=0;
  relation11 r;
  r=&(FieldClassFieldTypes[i]);
  while (r->name!=NULL) {
    if (strcmp(r->name,n)==0)
      return(r->class);
    r=&(FieldClassFieldTypes[++i]);
  }
  Al_fatal_error("AlRule_get_class_from_name: passed bad field class\n");
  return((AlRFType)NULL); /* for compilers */
}


/*--------------------------------------------------*/
char* AlRule_get_name_from_class(c)
     AlRFType c;
{
  int i=0;
  relation11 r;
  r=&(FieldClassFieldTypes[i]);
  while (r->name!=NULL) {
    if (r->class==c)
      return(r->name);
    r=&(FieldClassFieldTypes[++i]);
  }
  Al_fatal_error("AlRule_get_name_from_class: passed bad field class\n");
  return((char*)NULL); /* for compilers */
}



/*--------------------------------------------------*/
AlRule AlRule_create_default_rule()
{
  AlMsgType DefaultMT;
  char *name;

  AlRule Rule;
  AlRuleMember AndBox;
  AlRuleAssoc  AndBoxAA;
  Darray       Actions=Darray_create();
  AlRuleMember RField;
  Darray       Fields=Darray_create();
  AlFieldCore  field;
  int i,l;
  char *ftn,*fieldOpName;
  Darray FOL;
  AlFieldType ft;

  /*
   * GET THE DEFAULT MSG TYPE 
   */
  DefaultMT=NULL;
  if (AlProfile_has_value(ALPROF_DEFRMT)==Bool_TRUE) {
    name=AlProfile_get_CP_val(ALPROF_DEFRMT);
    DefaultMT=AlMTreg_get_obj_with_name(name);
  }
  if (DefaultMT==NULL) {
    Darray MTnames=Darray_create();
    AlMTreg_get_all_msg_type_names(MTnames);
    if (Darray_len(MTnames)>0) 
      DefaultMT=AlMTreg_get_obj_with_name((char*) Darray_get(MTnames,
							     (unsigned)0));
  }
  if (DefaultMT==NULL)
    Al_warning("AlRule_create_default: could not get default message type.\n");

  /*
   * CREATE THE PREDICATE PART 
   */
  AndBox=AlRuleMember_mcreate_assoc(ALRAT_AND);
  AndBoxAA=AlRuleMember_get_assoc(AndBox);
  if (DefaultMT!=NULL)
    AlMsgType_all_fields(DefaultMT,Fields);
  l=Darray_len(Fields);
  for (i=0;i<l;i++) {
    field=(AlFieldCore)Darray_get(Fields,i);
    assert(field);
      
    /* get field type */
    ft=AlFieldCore_get_field_type(field);
    assert(ft);

    /* get field operator name */
    FOL=Darray_create();
    AlFieldType_get_field_op_list(ft,FOL);
    if (Darray_len(FOL)<1) 
      Al_fatal_error1("could not find field operator for field tyoe %s.\n",
		      AlFieldCore_get_field_type_name(field));
    else 
      fieldOpName=(char*)Darray_get(FOL,(unsigned)0);
    Darray_destroy(FOL);

    /* get field type name */
    ftn=AlFTreg_obj_to_string(ft);
    RField=AlRuleMember_mcreate_field(ALRFT_MSG,
				      AlFieldCore_get_key(field),
				      ftn,
				      "",
				      fieldOpName);
    assert(RField);

    /* insert the new field into the and box */
    AlRuleAssoc_make_member_of(AndBoxAA,RField);
  }
  Darray_destroy(Fields);

  /* Create the Actions Part */
  if (AlProfile_has_value(ALPROF_DEF_RULE_VERBS)==Bool_TRUE) {
    Darray DefVerbs=Darray_create();
    Darray VerbNames=Darray_create();
    Darray VerbObjs=Darray_create();
    char *vns=AlProfile_get_CP_val(ALPROF_DEF_RULE_VERBS);
    char *defv;
    Bool exists;
    int i,l,j,l2;
    
    /* get the verb names */
    AlVerbReg_get_verbs(VerbNames,VerbObjs);
    
    /* get the verbs which go into the default rule from the profile */
    RapList_parse_into_darray(DefVerbs,vns);
    l=Darray_len(DefVerbs);
    l2=Darray_len(VerbNames);
    for (i=0;i<l;i++) {
      defv=(char*)Darray_get(DefVerbs,i);
      exists=Bool_FALSE;
      for (j=0;j<l2;j++) {
	if (strcasecmp(defv,(char*)Darray_get(VerbNames,j))==0) {
	  defv=Darray_get(VerbNames,j); /* make sure case is right */
	  exists=Bool_TRUE;
	  break;
	}
      }
      if (exists==Bool_TRUE) {
	Darray the_args=Darray_create();
	AlVerb the_verb;
	int num_args, m;
	
	the_verb=AlVerbReg_get_obj(defv);
	assert(the_verb);
	  /* create an array of dummy args */
	num_args=AlVerb_def_args(the_verb);
	for (m=0;m<num_args;m++) Darray_addh(the_args,(VOIDP)"");
	Darray_addh(Actions,AlAction_create(the_verb,the_args));
	Darray_destroy(the_args);
      }
      else {
	Al_warning1("ruleeditor: the verb %s appearing in your DefaultRuleVerbs\n", 
		    defv);
	Al_warning("            profile component is not a valid verb.\n");
      }
    }
    RapList_destroy_darray_contents(DefVerbs);
    Darray_destroy(DefVerbs);
    Darray_destroy(VerbNames);
    Darray_destroy(VerbObjs);
  }


  Rule=AlRule_create(AndBox,Actions,(time_t)0,(time_t)0,(char*)"<no name>");
  assert(Rule);
/*   Darray_destroy(Actions); */
  return(Rule);
}
  
  
