#ifndef LAYOUT_H_
#define LAYOUT_H_

#ifdef NOT_AN_RT
#include	<time.h>
#include	"/usr/include/sys/time.h"
#endif

#define	TEXTINPUT	11
#define	NUMERICINPUT	12
#define	SELECTIONINPUT	13
#define	BOOLEANINPUT	14

#define	TEXTDISPLAY	21
#define	BOXDISPLAY	22
#define	LINEDISPLAY	23

#define ISINPUT(x)      ((x) < 21)

#define NOINPUTTYPE     0
#define	INPUT		1
#define	DISPLAY		2

#define	EXCLUSIVE	0
#define	NONEXCLUSIVE	1

#define	HORIZONTAL	1
#define	VERTICAL	2

#define	STRLEN		45
#define	MAXSETITEMS	25

#define	EMPTYTOKEN	"NULL"
#define		DBPATH		"/afs/athena.mit.edu/astaff/project/forms/db/"

#ifndef Bool
typedef	int	Bool;
#endif

/* Value: this structure is used to pass around values of fields. It can be
   a string, or an int, or a double, etc. */

#define ValueEmpty 0
#define ValueString 1
#define ValueInt 2
#define ValueDouble 3
#define ValueBool 4
#define ValueIntList 5

typedef struct {
  char t;			/* the type of the value */
  union {
    char *s;
    int i;
    double d;
    Bool b;
    int *il;
  } v;
} Value;


#define WrapNone 0
#define WrapChar 1
#define WrapWord 2

typedef struct {
  char *calculate;
  char *data;
  char *defaultvalue;
  int length;
  char wrap;
  int numlines;
} TextInput, *TextInputPtr;

typedef struct {
  char *calculate;
  int data;
  int defaultvalue;
} NumericInput, *NumericInputPtr;

typedef struct {
  char *calculate;
  Bool data;
  Bool defaultvalue;
} BooleanInput, *BooleanInputPtr;

#define SelectionTypeExclusive 0
#define SelectionTypeNonexclusive 1
typedef struct {
  char *calculate;
  int *data;
  int *defaultvalues;
  int columns;
  int num_of_choices;		/* private */
  char **choices;
/*  char *type; */ /* Made this into an integer just because. */
  int type;
} SelectionInput, *SelectionInputPtr;

typedef struct {
	char	*data;
} TextDisplay, *TextDisplayPtr;

typedef struct {
	int	height, width;
} BoxDisplay, *BoxDisplayPtr;

typedef struct {
	int	direction;
	int	length;
} LineDisplay, *LineDisplayPtr;

typedef union {
	TextDisplayPtr	text;
	BoxDisplayPtr	box;
	LineDisplayPtr	line;
} DisplayType, *DisplayTypePtr;

typedef union {
	TextInputPtr		text;
	NumericInputPtr		numeric;
	BooleanInputPtr		boolean;
	SelectionInputPtr	selection;
} InputType, *InputTypePtr;

typedef struct displayfield {
	int			display_type;
	DisplayTypePtr		display;
} DisplayField, *DisplayFieldPtr;

typedef struct inputfield {
	int	input_type;
	int	distance;
	char	*prompt;
	InputTypePtr		inputsource;
} InputField, *InputFieldPtr;

typedef union {
	InputFieldPtr		inputptr;
	DisplayFieldPtr		displayptr;
} FieldType, *FieldTypePtr;

#define TextAttrBold 0x01
#define TextAttrItalic 0x02
#define TextAttrPlain 0x00

typedef struct field {
	char		*name;
	int		field_type;
	int		row, col;
	int		*screen;
/*	char		*textattrs; */
	int             textattrs;
	struct field	*realup, *realdown, *realright, *realleft;
	char		*up, *down, *right, *left;
	char		*helptext;
	char		*lockedif;
	char		*hiddenif;
	void            *userdata;
	int             flags;
	struct field	**dependents;
	FieldTypePtr	detail;
} Field, *FieldPtr;

#define FieldCalculating 0x04
#define FieldIsCalculation 0x08
#define FieldCalculated 0x10

#define FieldLocked 0x01
#define FieldHidden 0x02
#define FieldNormal 0x00
#define FieldVisibility(f) ((f)->flags & 0x03)
#define SetFieldVisibility(f, p) ((f)->flags = ((f)->flags & ~0x03) | (p))

#define xzSetFlag(p, f) ((p)->flags |= f)
#define xzSetFlags(p, f) ((p)->flags = f)

#define xzClearFlag(p, f) ((p)->flags &= ~f)
#define xzClearAllFlags(p) ((p)->flags = 0)

#define xzTestFlag(p, f) ((p)->flags & f)
#define xzTest xzTestFlag

typedef union{
	FieldPtr		field;
	InputFieldPtr		inputfield;
	DisplayFieldPtr		displayfield;
	TextInputPtr		text;
	NumericInputPtr		numeric;
	BooleanInputPtr		boolean;
	SelectionInputPtr	selection;
	TextDisplayPtr		textdisp;
	BoxDisplayPtr		boxdisp;
	LineDisplayPtr		linedisp;
} Generic, *GenericPtr;

/*
** The following structures are used in the definition of a form CLASS.
*/

typedef struct action {
	char		*label;		/* label on the button		*/
	int 		nextnode;	/* node it gets moved to	*/
} Action, *ActionPtr;

typedef struct node {
	int		nodenumber;
	char		*statusstring;	/* description of status	*/
	ActionPtr	*actionlist;	/* list of buttons and node	*/
	char		*defaultqueue;	/* who gets it by default	*/
	Bool		terminal;	/* True if this is a final state*/
#ifdef	NONDYNAMIC
	char		*hidden;	/* list of hidden fields' names	*/
	char		*locked;	/* list of locked fields' names	*/
#endif
	int		notify;		/* should new owner get zwrite? */
} Node, *NodePtr;

/*
** The definition of a form class is a list of fields defining the
** screen appearance of the form, plus a list of nodes which define the
** route it travels along.
*/

typedef struct formclass {
	char		*formname;	/* name of this class of form	*/
	FieldPtr	*topfield;	/* pointer to field list	*/
	int		fieldcount;
	NodePtr		*topnode;	/* pointer to route		*/
} Formclass, *FormclassPtr;

/*
** The following structures are used in the definition of a form INSTANCE.
*/

typedef struct history {
	int		oldnode;	/* moved from this node...	*/
	int		newnode;	/* to this one			*/
#ifdef NOT_AN_RT
	struct timeval	time;		/* at this time			*/
#endif
	char		*person;	/* by this person		*/
	struct history	*next;		/* next entry in history	*/
	struct Fieldvalue	*oldval;	/* changed value	*/
} History, *HistoryPtr;

typedef struct fieldval {
	char	*name;			/* name of field		*/
	char	*value;			/* value (possibly a cast int)	*/
	struct	Fieldvalue	*next;	/* next entry in value list	*/
} Fieldvalue, *FieldvaluePtr;

/*
** A form instance is a pointer to a form class, plus the information for
** this specific form:  Current node and owner, history, and values
** of the form's fields.
*/

typedef struct forminstance {
	FormclassPtr	class;		/* info on this type of form	*/
	NodePtr		currentnode;	/* pointer to its current node	*/
	char		*owner;		/* userid or NULL if not owned	*/
	char		*queue;		/* queue it's waiting on	*/
	HistoryPtr	*history;	/* list of old values		*/
} Forminstance, *ForminstancePtr;

char Eval(char *, ForminstancePtr, Value *);
char EvalFormclass(char *, FormclassPtr, Value *);

typedef struct {
  void (*visibilityf)(), (*calculationf)();
  void *visibilitycb, *calculationcb;
} CalculationCallbacks;

void SetCalculationCallbacks(void (*visibilityf)(), void *visibilitycb,
			     void (*calcf)(), void *calccb);
void CopyCalculationCallbacks(CalculationCallbacks c);
CalculationCallbacks GetCalculationCallbacks(void);

void CalculateVisibility(ForminstancePtr, FieldPtr);
void CalculateField(ForminstancePtr, FieldPtr);

FieldPtr FindFieldByName(char *targetname, FormclassPtr pinstance);

ForminstancePtr ReadFormDefinition(char *deffile, char *datafile);
ForminstancePtr ReadFormDefinitionFromDatabase(char *clas, char *instancename);

char FormWrite(ForminstancePtr form, char *into);
char FormWriteIntoDatabase(ForminstancePtr form, char *clas, char *formname);

int AssignToOwner(ForminstancePtr, char *clas, char *formname, char *owner);

#endif
