/* Copyright 1989, 1990 by James Aspnes, David Applegate, and Bennet Yee */
/* See the file COPYING for distribution information */
#ifndef _DB_H
#define _DB_H

#include <stdio.h>
#include "alist.h"
#include "set.h"

/* this must appear at the beginning of all database files */
#define DB_HEADER "### TinyMUD 2.4 database format ###\n"

typedef datum object_flag_type;

#define F_OPEN 0x1		/* anything can be moved here */
#define F_CONNECTED 0x2		/* this object is connected to somebody */
#define F_PARANOID 0x4		/* annotate tells with the sender */

#define F_PLAYER 0x10		/* this object is a player */
#define F_BUILDER 0x20		/* this object may create objects */
#define F_PROGRAMMER 0x40	/* this object may set code fields */
#define F_WIZARD 0x80		/* this object controls everything */
#define F_ADMIN 0x100		/* this object can shut th system down */

/* names for above */
#define isflagname(name) ((name) >= MIN_FLAGNAME && (name) < MAX_FLAGNAME)
#define name2flag(name) (1 << ((name) - MIN_FLAGNAME))

/* for struct object *'s */
#define oflag_set(o, flag) ((o)->flags & flag)

struct object {
    alist vars;			/* values are datum's, different types */
    alist sets;			/* values are pointers to sets of objects */
    alist actions;		/* values are reified code objects */
    datum owner;		/* what object owns this one */
    datum parent;		/* object we inherit from */
    datum location;		/* where we are */
    object_flag_type flags;	/* various useful bits */
};

/* String stuff */
extern datum intern(const char *); /* intern a string into the string table */
extern datum intern_soft(const char *);	/* won't put a new entry in */
extern const char *string(datum); /* returns the print name of the string */

/* compiled strings */
extern void set_compiled_string(datum s, datum *code);
extern datum *get_compiled_string(datum s);

/* alias expansions */
extern void set_expansion(datum s, alist);
extern alist get_expansion(datum s);

/* Objects */
/* every object has an owner */
extern datum new_object(datum owner);
extern void free_object(datum);
extern struct object *object(datum); /* get the struct */

/* use this to read fields off of an object */
#define safe_get(obj, field) \
 ((_safe_get_TMP = object(obj)) ? _safe_get_TMP->field : NOTHING)
extern struct object *_safe_get_TMP;

/* Garbage collector */
extern void gc_mark_string(datum);
extern void full_gc(void);
extern void incremental_gc();

/* I/O */
extern int db_write(FILE *);
extern int db_read(FILE *);

/* Iteration */
extern int foreach_object(void (*func)(datum));

#endif /* _DB_H */