/* $Header: unparse.c,v 2.0 90/05/05 12:45:46 lachesis Exp $
 * $Log:	unparse.c,v $
 * Revision 2.0  90/05/05  12:45:46  lachesis
 * Incorporated ABODE and HAVEN flags (remembering to convert FireFoot's
 * usage of those flags to ours).
 * Added Examine of objects that don't belong to you, added GOD_PRIV.
 * 
 * Revision 1.2  90/04/21  17:20:52  lachesis
 * Added property lists.
 * 
 * Revision 1.1  90/04/14  14:56:56  lachesis
 * Initial revision
 * 
 */
#include "db.h"

#include "externs.h"
#include "config.h"
#include "interface.h"

static const char *unparse_flags(dbref thing)
{
    static char buf[BUFFER_LEN];
    char *p;
    const char *type_codes = "R-EP";

    p = buf;
    if(Typeof(thing) != TYPE_THING) *p++ = type_codes[Typeof(thing)];
    if(db[thing].flags & ~TYPE_MASK) {
	/* print flags */
	if(db[thing].flags & WIZARD) *p++ = 'W';
	if(db[thing].flags & STICKY) *p++ = 'S';
	if(db[thing].flags & DARK) *p++ = 'D';
	if(db[thing].flags & LINK_OK) *p++ = 'L';
	if(db[thing].flags & TEMPLE) *p++ = 'T';
#ifdef RESTRICTED_BUILDING
	if(db[thing].flags & BUILDER) *p++ = 'B';
#endif /* RESTRICTED_BUILDING */
#ifdef PLAYER_CHOWN
	if(db[thing].flags & CHOWN_OK) *p++ = 'C';
#endif /* PLAYER_CHOWN */
	if(db[thing].flags & JUMP_OK) *p++ = 'J';
#ifdef HAVEN
	if (db[thing].flags & HAVEN) *p++ = 'H';
#endif /* HAVEN */
#ifdef ABODE
	if (db[thing].flags & ABODE) *p++ = 'A';
#endif /* ABODE */
    }
    *p = '\0';
    return buf;
}

const char *unparse_object(dbref player, dbref loc)
{
    static char buf[BUFFER_LEN];

    switch(loc) {
      case NOTHING:
	return "*NOTHING*";
      case HOME:
	return "*HOME*";
      default:
	if(controls(player, loc) || can_link_to(player, loc)
#ifdef PLAYER_CHOWN
	   || (db[loc].flags & CHOWN_OK)
#endif /* PLAYER_CHOWN */
	   ) {
	    /* show everything */
	    sprintf(buf, "%s(#%d%s)", db[loc].name, loc, unparse_flags(loc));
	    return buf;
	} else {
	    /* show only the name */
	    return db[loc].name;
	}
    }
}

static char boolexp_buf[BUFFER_LEN];
static char *buftop;

static void unparse_boolexp1(dbref player,
			     struct boolexp *b, boolexp_type outer_type)
{
    if(b == TRUE_BOOLEXP) {
	(void) strcpy(buftop, "*UNLOCKED*");
	buftop += strlen(buftop);
    } else {
	switch(b->type) {
	  case BOOLEXP_AND:
	    if(outer_type == BOOLEXP_NOT) {
		*buftop++ = '(';
	    }
	    unparse_boolexp1(player, b->sub1, b->type);
	    *buftop++ = AND_TOKEN;
	    unparse_boolexp1(player, b->sub2, b->type);
	    if(outer_type == BOOLEXP_NOT) {
		*buftop++ = ')';
	    }
	    break;
	  case BOOLEXP_OR:
	    if(outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND) {
		*buftop++ = '(';
	    }
	    unparse_boolexp1(player, b->sub1, b->type);
	    *buftop++ = OR_TOKEN;
	    unparse_boolexp1(player, b->sub2, b->type);
	    if(outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND) {
		*buftop++ = ')';
	    }
	    break;
	  case BOOLEXP_NOT:
	    *buftop++ = '!';
	    unparse_boolexp1(player, b->sub1, b->type);
	    break;
	  case BOOLEXP_CONST:
	    (void) strcpy(buftop, unparse_object(player, b->thing));
	    buftop += strlen(buftop);
	    break;
	  case BOOLEXP_PROP:
	    (void) strcpy(buftop, b -> prop_check -> type);
	    (void) strcat(buftop, ":");
	    (void) strcat(buftop, b -> prop_check -> class);
	    buftop += strlen(buftop);
	    break;
	  default:
	    abort();		/* bad type */
	    break;
	}
    }
}
	    
const char *unparse_boolexp(dbref player, struct boolexp *b)
{
    buftop = boolexp_buf;
    unparse_boolexp1(player, b, BOOLEXP_CONST);	/* no outer type */
    *buftop++ = '\0';

    return boolexp_buf;
}