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

#define T_ROOM     0x1
#define T_THING    0x2
#define T_EXIT     0x4
#define T_PLAYER   0x8
#define T_PROGRAM  0x10
#define T_ALL      0x1F
#define T_NONE     0x0

struct flist {
  const char *name;
  object_flag_type the_flag;
  const char *sname;
  object_flag_type type_check;
} flag_list[]={
  "WIZARD",   WIZARD,     "W", T_ALL,
  "LINK_OK",  LINK_OK,    "L", T_ALL,
  "DARK",     DARK,       "d", T_ROOM | T_EXIT | T_PLAYER | T_THING,
  "DEBUG",    DARK,       "d", T_PROGRAM,
  "SETUID",   STICKY,     "S", T_PROGRAM,
  "SILENT",   STICKY,     "S", T_PLAYER,
  "STICKY",   STICKY,     "S", T_ROOM | T_EXIT | T_THING,
  "BUILDER",  BUILDER,    "B", T_ALL,
#ifdef PLAYER_CHOWN
  "CHOWN_OK", CHOWN_OK,   "C", T_ALL,
#endif
  "JUMP_OK",  JUMP_OK,    "J", T_ALL,
#ifdef HAVEN
  "HAVEN",    HAVEN,      "H", T_ROOM | T_EXIT | T_PLAYER,
  "HALTED",   HALTED,      "H", T_THING | T_PROGRAM,
#else
  "HALTED",   HALTED,      "H", T_ALL,
#endif  /* HAVEN */
  "QUELL",    QUELL,      "q", T_ALL,
  "PUPPET",   PUPPET,     "p", T_ROOM | T_EXIT | T_THING | T_PROGRAM,
  "PARANOID", PUPPET,     "p", T_PLAYER,
  "VISIBLE",  VISIBLE,    "V", T_ALL,
#ifdef ABODE
  "ABODE",    ABODE,      "A", T_ROOM,
  "ARCHITECT", ARCHITECT, "A", T_EXIT | T_PLAYER | T_PROGRAM | T_THING,
#else /* ABODE */
  "ARCHITECT", ARCHITECT, "A", T_ALL,
#endif
  "MURKY",    MAGE,       "M", T_ROOM | T_THING | T_EXIT,
  "MAGE",     MAGE,       "M", T_PLAYER | T_PROGRAM,
  (const char *)0, 0, (const char *)0,
};

object_flag_type filter_type(object_flag_type type)
{
  switch(type) {
  case TYPE_ROOM:
    return T_ROOM;
    break;
  case TYPE_THING:
    return T_THING;
    break;
  case TYPE_EXIT:
    return T_EXIT;
    break;
  case TYPE_PLAYER:
    return T_PLAYER;
    break;
  case TYPE_PROGRAM:
    return T_PROGRAM;
    break;
  default:
    return T_NONE;
  }
}

object_flag_type lookup_flag(const char *name)
{
  struct flist *f;
  object_flag_type res = 0;

  if(!name) return 0;
  if(!*name) return 0;

  for(f = flag_list; f->name && !res; f++)
    if(string_prefix(f->name, name)) {
      res = f->the_flag;
    }
  return res;
}

const char *unparse_flag(object_flag_type x)
{
  static char buf[BUFFER_LEN];
  struct flist *f;
  object_flag_type o_type;

  o_type = filter_type(x&TYPE_MASK);

  (*buf) = buf[1] = '\0';
  for(f = flag_list; f->name; f++)
    if((x&f->the_flag) && (o_type&f->type_check) && *f->sname) {
      strcat(buf," ");
      strcat(buf, f->name);
    }
  return buf+1;
}

const char *unparse_flag_short(object_flag_type x)
{
  static char buf[BUFFER_LEN];
  struct flist *f;
  object_flag_type o_type;
  *buf = '\0';
  
  o_type = filter_type(x&TYPE_MASK);
  
  for(f = flag_list; f->name; f++)
    if((x&f->the_flag) && (o_type&f->type_check))
      strcat(buf, f->sname);
  return buf;
}