#ifndef RL_H
#define RL_H 1

#include "res.h"
#include "darray.h"
#include "menupack.h"
#include "verb.h"
#include "rule.h"
#include "biregistry.h"
#include "bool.h"
#include "sysdep.h"
#include "FieldType.h"
#include "global.h"

#define KEY_LENGTH   200
#define DEFAULT_FIELD_TYPE "SubString"
#define ARGUMENT_LENGTH       500
#define VALUE_LENGTH          50

typedef struct {
    int  firstPos;
    int  length;
    char *ptr;
    Atom format;
    } XtTextBlock, *XtTextBlockPtr;

typedef struct REMember_str {
  AlRMType Type;
  union {
    struct REField_str *Field;
    struct REAssoc_str *Assoc;
  } object;
  struct REMember_str *father;
} *REMember;

typedef struct REAssoc_str {
  Darray         Contents; /* of REMembers */
  reid           rei;        /* !!! this should be put intop the REmember */
  REMember       container;
  AlRAType       Type;
  Widget         ContainerW;
  Widget         LabelW;
  MenuPack       Menu;
} *REAssoc;

#ifdef __STDC__
typedef enum FromWhere_en { REF_FROM_TEMPLATE, REF_FROM_USER } REFromWhere;
#else
typedef int REFromWhere;
#define REF_FROM_TEMPLATE 0
#define REF_FROM_USER     1
#endif

typedef struct REField_str {
  reid           rei;
  REMember       container;
  REFromWhere    FromWhere;
  AlRFType       Type;
  Bool           IsState;
  AlFieldType    FieldTypeObject;
  char *         FieldType;
  char *         FieldOp;
  char *         defaultFieldOp;
  MenuPack       AltsMenu;
  MenuPack       FTMenu;   /* depends on field type */
  Widget         KeyW;
  Widget         ValueW;
  Widget         AltsMenuW, FTMenuW;  /* the box widgets */
  Widget         FTMenuLabelW;        /* where the menu attaches.  this is */
				      /* the widget you make insenitive to */
				      /* disable the menu. */
  Widget         AltsMenuAttachW; /* we need this to dynamically replace the */
				  /* submenu.  Not that the other menu */
				  /* widgets are the box widgets surrounding */
				  /* the label widgets.  The menu attach */
				  /* point is the label widget itself--which */
				  /* is this widget in this case. */
  Widget         ContainerW;
  char           *ValueBuffer;
  char           *Value;
  char           *Key;
  Bool           ExistanceOp;
  char           *ValueBufferSave;  /* used by the existance mechanism */
  char           MyAddress[17];  /* this is used to identify this object */
				 /* when making X event callbacks. */
  char*          predValTranslations; /* a special list of translations for*/
                                /* predicate value widget. */
  char*          predKeyTranslations; /* same list but for the key, only */
				      /* used when they key is editable, */
				      /* used to ensure that colons follow */
				      /* all field names. */
  Bool           ValueIsParsable;
} *REField;

typedef struct FieldRet_str {
  char * name;
  REField  Field;
} *FieldRet;

typedef struct FTOpRet_str {
  char * fieldOp;
  REField Field;
} *FTOpRet;

typedef struct REArgument_str {
  char *Arg;
  short InitialArgLength;
  Widget MenuW, ArgW;
  MenuPack Menu;
} *REArgument;

typedef struct REAction_str {
  AlVerb    Verb;
  char *    VerbName;
  Widget    MenuW, VerbW;
  Widget    ContainerW;
  Darray    Arguments;
  MenuPack  Menu;
} *REAction;

typedef struct REVerbRet_str {
  char      *name;
  REAction  Action;
} *REVerbRet;

typedef struct REArgRet_str {
  REArgument arg;
  REAction action;
} *REArgRet;

#define ARGUMENT_ADD_FUNCTION_MENU_NAME "Add Argument To End"
#define ARGUMENT_DEL_FUNCTION_MENU_NAME "Delete This Argument"

#ifdef __STDC__
extern void            rl_Init (reid);
extern REMember        rl_REMember_create(AlRMType, VOIDP, REMember);
extern REMember        rl_REMember_create_at_index(AlRMType,VOIDP, 
						   REMember, int);
extern NORET           rl_REMember_destroy(REMember);
extern int             rl_REMember_get_index(REMember);
extern REField 	rl_REField_create(reid,AlRFType,char*,char*,char*,char*,
				  REFromWhere);
extern MenuPack 	rl_MakeAltsMenu(REField);
extern MenuPack 	rl_MakeFTMenu(reid,REField);
extern void 		rl_SelectFT_CB(Widget,FieldRet,caddr_t);
extern FieldRet 	FieldRet_create(char*,REField);
extern REAssoc 	rl_REAssoc_create(reid,AlRAType);
extern MenuPack 	rl_REAssoc_MakeMenu(REAssoc);
extern REArgument 	rl_REArgument_create(reid,char*,REAction);
extern REAction 	rl_REAction_create(reid,char*,Darray);
extern MenuPack 	rl_REAssoc_MakeMenu(REAssoc);
extern MenuPack 	rl_REAction_MakeMenu(reid,REAction,REArgument);
extern MenuPack 	rl_REAction_create_verbs_menu(reid,REAction);
extern REMember 	rl_TranslateToRE(reid,AlRuleMember);
extern REMember 	rl_TranslateFieldToRE(reid,AlRuleMember,REMember);
extern REMember 	rl_TranslateAssocToRE(reid,AlRuleMember,REMember);
extern Darray 		rl_TranslateActionsToRE(reid,Darray);
extern Darray 		rl_TranslateActionsFromRE(reid,Darray);
extern AlRuleMember 	rl_TranslateFromRE(reid,REMember);
extern AlRuleMember 	rl_TranslateFieldFromRE(reid,REMember,AlRuleMember);
extern AlRuleMember 	rl_TranslateAssocFromRE(reid,REMember,AlRuleMember);
extern REField		rl_REField_duplicate(reid,REField);
extern REVerbRet       rl_REVerbRet_create(char*,REAction);
extern void            rl_RegSelectFC_CB(Widget,FieldRet,caddr_t);
extern void            rl_StateSelectFC_CB(Widget,FieldRet,caddr_t);
extern Bool            rl_IsState(AlRFType);
extern void            rl_MenuSensitiveOnly(MenuPack,Darray,char *);
extern void            rl_MenuSensitiveAll(MenuPack,Darray);
extern void            rl_MenuInsensitiveAll(MenuPack,Darray);
extern Darray          rl_Darray_remove_ptr(Darray,VOIDP);
extern Darray          rl_Darray_insert(Darray,VOIDP,int);
extern void            rl_SelectFieldOp_CB(Widget,caddr_t,caddr_t);
extern Bool            rl_Field_op_is_valid(AlFieldType,char*);
extern NORET           rl_Parse_list_into_darray(Darray,char*);
extern NORET           rl_Parse_list_into_darray_destroy(Darray);
extern NORET           rl_Existance_CB(Widget,caddr_t,caddr_t);
extern NORET           rl_Existance_reset_from(REField);
extern Darray          rl_Actions_get_defaults(reid);
extern void            rl_Monitor_field_key(Widget,XEvent*,String*,Cardinal*);
extern void            rl_Monitor_field_value(Widget,XEvent*,String*,Cardinal*);
extern void            rl_Modified_rule(Widget,XEvent*,String*,Cardinal*);
extern char *          rl_REField_make_translation(char*,char*,char*);
extern char *          rl_REField_augment_translations(char*,char*,char*,char*);
extern REField         rl_REField_get_field_from_address(char*);
extern NORET           rl_REField_register_address(REField);
extern NORET           rl_REField_remove_address(REField);
extern Pixmap          rl_get_pixmap(reid,unsigned);
extern void            rl_Parse_field_and_update(REField);
extern char *          rl_Key_rj_and_add_colon(char*,int,int*);
extern Widget          rl_Get_widget_from_member(REMember);
extern NORET           rl_Get_surrounding_widgets(reid,REMember,
					   Widget*,Widget*,Widget*);
extern NORET           rl_Get_surrounding_members(reid,REMember,
					   REMember*,REMember*,REMember*);
#else
extern void            rl_Init();
extern REMember 	rl_REMember_create();
extern REMember 	rl_REMember_create_at_index();
extern NORET           rl_REMember_destroy();
extern int             rl_REMember_get_index();
extern REField 	rl_REField_create();
extern MenuPack 	rl_MakeAltsMenu();
extern MenuPack 	rl_MakeFTMenu();
extern void 		rl_SelectFT_CB();
extern FieldRet 	FieldRet_create();
extern REAssoc 	rl_REAssoc_create();
extern MenuPack 	rl_REAssoc_MakeMenu();
extern REArgument 	rl_REArgument_create();
extern REAction 	rl_REAction_create();
extern MenuPack 	rl_REAssoc_MakeMenu();
extern MenuPack 	rl_REAction_MakeMenu();
extern MenuPack 	rl_REAction_create_verbs_menu();
extern REMember 	rl_TranslateToRE();
extern REMember 	rl_TranslateFieldToRE();
extern REMember 	rl_TranslateAssocToRE();
extern Darray 		rl_TranslateActionsToRE();
extern Darray 		rl_TranslateActionsFromRE();
extern AlRuleMember 	rl_TranslateFromRE();
extern AlRuleMember 	rl_TranslateFieldFromRE();
extern AlRuleMember 	rl_TranslateAssocFromRE();
extern REField		rl_REField_duplicate();
extern REVerbRet       rl_REVerbRet_create();
extern void            rl_RegSelectFC_CB();
extern void            rl_StateSelectFC_CB();
extern Bool            rl_IsState();
extern void            rl_MenuSensitiveOnly();
extern void            rl_MenuSensitiveAll();
extern void            rl_MenuInsensitiveAll();
extern Darray          rl_Darray_remove_ptr();
extern Darray          rl_Darray_insert();
extern void            rl_SelectFieldOp_CB();
extern Bool            rl_Field_op_is_valid();
extern NORET           rl_Parse_list_into_darray();
extern NORET           rl_Parse_list_into_darray_destroy();
extern NORET           rl_Existance_CB();
extern NORET           rl_Existance_reset_from();
extern Darray          rl_Actions_get_defaults();
extern void            rl_Monitor_field_key();
extern void            rl_Monitor_field_value();
extern void            rl_Modified_rule();
extern char *          rl_REField_make_translation();
extern char *          rl_REField_augment_translations();
extern REField         rl_REField_get_field_from_address();
extern NORET           rl_REField_register_address();
extern NORET           rl_REField_remove_address();
extern Pixmap          rl_get_pixmap();
extern void            rl_Parse_field_and_update();
extern char *          rl_Key_rj_and_add_colon();
extern Widget          rl_Get_widget_from_member();
extern NORET           rl_Get_surrounding_widgets();
extern NORET           rl_Get_surrounding_members();
#endif


/* defenition of the action for monitoring fields */
/* there was a better way to do this, some macro... */
#define RL_NUMBER_OF_ACTIONS 3   
static XtActionsRec rl_Actions[]={
  {"rl_Monitor_field_value", rl_Monitor_field_value },
  {"rl_Monitor_field_key", rl_Monitor_field_key },
  {"rl_Modified_rule", rl_Modified_rule }
};
  
#define SOLID_LINE 1
#define solidline_width 10
#define solidline_height 10
static char solidline_bits[] = {
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

#define DASHED_LINE 2
#define dashedline_width 24
#define dashedline_height 24
static char dashedline_bits[] = {
   0x7f, 0x00, 0x80, 0x3f, 0x00, 0xc0, 0x1f, 0x00, 0xe0, 0x0f, 0x00, 0xf0,
   0x07, 0x00, 0xf8, 0x03, 0x00, 0xfc, 0x01, 0x00, 0xfe, 0x00, 0x00, 0xff,
   0x00, 0x80, 0x7f, 0x00, 0xc0, 0x3f, 0x00, 0xe0, 0x1f, 0x00, 0xf0, 0x0f,
   0x00, 0xf8, 0x07, 0x00, 0xfc, 0x03, 0x00, 0xfe, 0x01, 0x00, 0xff, 0x00,
   0x80, 0x7f, 0x80, 0xc0, 0x3f, 0xc0, 0xe0, 0x1f, 0xe0, 0xf0, 0x0f, 0xf0,
   0xf8, 0x07, 0xf8, 0xfc, 0x03, 0xfc, 0xfe, 0x01, 0xfe, 0xff, 0x00, 0xff};

/*
#define dashedline_width 8
#define dashedline_height 8
static char dashedline_bits[] = {
   0x33, 0x99, 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66};
*/
#endif
