/* $Header: /belch_a/users/rearl/tinymuck/src/RCS/unparse.c,v 1.6 90/09/18 08:02:47 rearl Exp $ */

/*
 * $Log:	unparse.c,v $
 * Revision 1.6  90/09/18  08:02:47  rearl
 * Took out FILTER.
 * 
 * Revision 1.5  90/09/16  04:43:11  rearl
 * Preparation code added for disk-based MUCK.
 * 
 * Revision 1.4  90/08/27  03:34:48  rearl
 * Took out TEMPLE, other stuff.
 * 
 * Revision 1.3  90/08/11  04:11:41  rearl
 * *** empty log message ***
 * 
 * Revision 1.2  90/08/06  03:50:27  rearl
 * Added unparsing of ROOMS (exits? programs?) if they are CHOWN_OK.
 * 
 * Revision 1.1  90/07/19  23:04:17  casie
 * Initial revision
 * 
 *
 */

#include "copyright.h"
#include "config.h"

#include "db.h"
#include "externs.h"
#include "params.h"
#include "interface.h"

char buf[BUFFER_LEN]; /* the global one! */

const char *unparse_object(dbref player, dbref loc)
{
  char buf[BUFFER_LEN];
  const char *type_codes = "R-EPFXG";

  switch(loc) {
  case NOTHING:
    return "*NOTHING*";
  case HOME:
    return "*HOME*";
  default:
    if (can_link_to(player, NOTYPE, loc) ||
	(FLAGS(loc)&VISIBLE) ||
	(Arch(player)) ||
#ifdef PLAYER_CHOWN
	(FLAGS(loc)&CHOWN_OK)
#endif /* PLAYER_CHOWN */
	)
      {
	/* show everything */
	sprintf(buf, "%s(#%d%c%s)", NAME(loc), loc, type_codes[Typeof(loc)],
		unparse_flag_short(FLAGS(loc)));
	return buf;
      } else {
	/* show only the name */
	return NAME(loc);
      }
  }
}

#define OVERFLOW 512
static char boolexp_buf[BUFFER_LEN];
static char *buftop;

static void unparse_boolexp1(dbref player,
			     struct boolexp *b, boolexp_type outer_type)
{
  if ((buftop - boolexp_buf) > (BUFFER_LEN - OVERFLOW)) {
    strcpy(buftop, "... <Overflow>");
    buftop += strlen(buftop);
  }
  else if(b == TRUE_BOOLEXP) {
    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:
      strcpy(buftop, unparse_object(player, b->thing));
      buftop += strlen(buftop);
      break;
    case BOOLEXP_PROP:
      strcpy(buftop, b -> prop_check -> type);
      strcat(buftop, ":");
      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;
}