dw_fluffos_v2/
dw_fluffos_v2/fluffos-2.9-ds2.05/
dw_fluffos_v2/fluffos-2.9-ds2.05/ChangeLog.old/
dw_fluffos_v2/fluffos-2.9-ds2.05/Win32/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/simuls/
dw_fluffos_v2/fluffos-2.9-ds2.05/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/clone/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/command/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/data/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/etc/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/master/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/log/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/compiler/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/efuns/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/operators/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/u/
dw_fluffos_v2/fluffos-2.9-ds2.05/tmp/
dw_fluffos_v2/fluffos-2.9-ds2.05/windows/
dw_fluffos_v2/lib/
dw_fluffos_v2/lib/binaries/cmds/
dw_fluffos_v2/lib/binaries/cmds/creator/
dw_fluffos_v2/lib/binaries/cmds/living/
dw_fluffos_v2/lib/binaries/cmds/player/
dw_fluffos_v2/lib/binaries/d/admin/obj/
dw_fluffos_v2/lib/binaries/d/liaison/
dw_fluffos_v2/lib/binaries/global/virtual/
dw_fluffos_v2/lib/binaries/global/virtual/setup_compiler/
dw_fluffos_v2/lib/binaries/obj/handlers/autodoc/
dw_fluffos_v2/lib/binaries/obj/handlers/terrain_things/
dw_fluffos_v2/lib/binaries/obj/misc/
dw_fluffos_v2/lib/binaries/obj/misc/buckets/
dw_fluffos_v2/lib/binaries/obj/monster/
dw_fluffos_v2/lib/binaries/obj/reactions/
dw_fluffos_v2/lib/binaries/obj/reagents/
dw_fluffos_v2/lib/binaries/secure/cmds/creator/
dw_fluffos_v2/lib/binaries/secure/master/
dw_fluffos_v2/lib/binaries/std/
dw_fluffos_v2/lib/binaries/std/dom/
dw_fluffos_v2/lib/binaries/std/effects/object/
dw_fluffos_v2/lib/binaries/std/guilds/
dw_fluffos_v2/lib/binaries/std/languages/
dw_fluffos_v2/lib/binaries/std/races/
dw_fluffos_v2/lib/binaries/std/room/
dw_fluffos_v2/lib/binaries/std/room/basic/
dw_fluffos_v2/lib/binaries/std/shops/
dw_fluffos_v2/lib/binaries/std/shops/inherit/
dw_fluffos_v2/lib/binaries/www/
dw_fluffos_v2/lib/cmds/guild-race/
dw_fluffos_v2/lib/cmds/guild-race/crafts/
dw_fluffos_v2/lib/cmds/guild-race/other/
dw_fluffos_v2/lib/cmds/playtester/
dw_fluffos_v2/lib/cmds/playtester/senior/
dw_fluffos_v2/lib/d/admin/
dw_fluffos_v2/lib/d/admin/log/
dw_fluffos_v2/lib/d/admin/mapper/31-10-01/mapmaker/event/
dw_fluffos_v2/lib/d/admin/meetings/
dw_fluffos_v2/lib/d/admin/obj/
dw_fluffos_v2/lib/d/admin/room/we_care/
dw_fluffos_v2/lib/d/admin/save/
dw_fluffos_v2/lib/d/dist/
dw_fluffos_v2/lib/d/dist/mtf/
dw_fluffos_v2/lib/d/dist/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/chars/
dw_fluffos_v2/lib/d/dist/pumpkin/desert/
dw_fluffos_v2/lib/d/dist/pumpkin/gumboot/
dw_fluffos_v2/lib/d/dist/pumpkin/hospital/
dw_fluffos_v2/lib/d/dist/pumpkin/inherit/
dw_fluffos_v2/lib/d/dist/pumpkin/map/
dw_fluffos_v2/lib/d/dist/pumpkin/plain/
dw_fluffos_v2/lib/d/dist/pumpkin/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/save/
dw_fluffos_v2/lib/d/dist/pumpkin/squash/
dw_fluffos_v2/lib/d/dist/pumpkin/terrain/
dw_fluffos_v2/lib/d/dist/pumpkin/woods/
dw_fluffos_v2/lib/d/dist/start/
dw_fluffos_v2/lib/d/learning/TinyTown/buildings/
dw_fluffos_v2/lib/d/learning/TinyTown/map/
dw_fluffos_v2/lib/d/learning/TinyTown/roads/
dw_fluffos_v2/lib/d/learning/add_command/
dw_fluffos_v2/lib/d/learning/arms_and_weps/
dw_fluffos_v2/lib/d/learning/chars/
dw_fluffos_v2/lib/d/learning/cutnpaste/
dw_fluffos_v2/lib/d/learning/examples/npcs/
dw_fluffos_v2/lib/d/learning/examples/player_houses/npcs/
dw_fluffos_v2/lib/d/learning/examples/terrain_map/basic/
dw_fluffos_v2/lib/d/learning/functions/
dw_fluffos_v2/lib/d/learning/handlers/
dw_fluffos_v2/lib/d/learning/help_topics/npcs/
dw_fluffos_v2/lib/d/learning/help_topics/objects/
dw_fluffos_v2/lib/d/learning/help_topics/rcs_demo/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/crowd/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/situations/
dw_fluffos_v2/lib/d/learning/items/
dw_fluffos_v2/lib/d/learning/save/
dw_fluffos_v2/lib/d/liaison/
dw_fluffos_v2/lib/d/liaison/NEWBIE/doc/
dw_fluffos_v2/lib/d/liaison/NEWBIE/save/oldlog/
dw_fluffos_v2/lib/db/
dw_fluffos_v2/lib/doc/
dw_fluffos_v2/lib/doc/creator/
dw_fluffos_v2/lib/doc/creator/autodoc/include/reaction/
dw_fluffos_v2/lib/doc/creator/autodoc/include/ritual_system/
dw_fluffos_v2/lib/doc/creator/autodoc/include/talker/
dw_fluffos_v2/lib/doc/creator/autodoc/include/terrain_map/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/baggage/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clock/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clothing/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/cont_save/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/corpse/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/money/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/monster/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/scabbard/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/service_provider/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/state_changer/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/wand/
dw_fluffos_v2/lib/doc/creator/autodoc/std/book_dir/
dw_fluffos_v2/lib/doc/creator/autodoc/std/key/
dw_fluffos_v2/lib/doc/creator/autodoc/std/learning/
dw_fluffos_v2/lib/doc/creator/autodoc/std/map/
dw_fluffos_v2/lib/doc/creator/autodoc/std/race/
dw_fluffos_v2/lib/doc/creator/autodoc/std/weapon_logic/
dw_fluffos_v2/lib/doc/creator/files/
dw_fluffos_v2/lib/doc/creator/policy/
dw_fluffos_v2/lib/doc/creator/room/
dw_fluffos_v2/lib/doc/effects/
dw_fluffos_v2/lib/doc/ideas/
dw_fluffos_v2/lib/doc/known_command/
dw_fluffos_v2/lib/doc/lpc/basic_manual/
dw_fluffos_v2/lib/doc/lpc/intermediate/
dw_fluffos_v2/lib/doc/new/add_command/
dw_fluffos_v2/lib/doc/new/handlers/
dw_fluffos_v2/lib/doc/new/living/
dw_fluffos_v2/lib/doc/new/living/race/
dw_fluffos_v2/lib/doc/new/living/spells/
dw_fluffos_v2/lib/doc/new/player/
dw_fluffos_v2/lib/doc/new/room/guild/
dw_fluffos_v2/lib/doc/new/room/outside/
dw_fluffos_v2/lib/doc/new/room/storeroom/
dw_fluffos_v2/lib/doc/object/
dw_fluffos_v2/lib/doc/playtesters/
dw_fluffos_v2/lib/doc/policy/
dw_fluffos_v2/lib/doc/weapons/
dw_fluffos_v2/lib/global/handlers/
dw_fluffos_v2/lib/global/virtual/setup_compiler/
dw_fluffos_v2/lib/include/
dw_fluffos_v2/lib/include/cmds/
dw_fluffos_v2/lib/include/effects/
dw_fluffos_v2/lib/include/npc/
dw_fluffos_v2/lib/include/shops/
dw_fluffos_v2/lib/net/daemon/chars/
dw_fluffos_v2/lib/net/inherit/
dw_fluffos_v2/lib/net/intermud3/
dw_fluffos_v2/lib/net/intermud3/services/
dw_fluffos_v2/lib/net/obj/
dw_fluffos_v2/lib/net/save/
dw_fluffos_v2/lib/net/smnmp/
dw_fluffos_v2/lib/net/snmp/
dw_fluffos_v2/lib/obj/amulets/
dw_fluffos_v2/lib/obj/b_day/
dw_fluffos_v2/lib/obj/examples/
dw_fluffos_v2/lib/obj/food/alcohol/
dw_fluffos_v2/lib/obj/food/chocolates/
dw_fluffos_v2/lib/obj/food/fruits/
dw_fluffos_v2/lib/obj/food/meat/
dw_fluffos_v2/lib/obj/food/nuts/
dw_fluffos_v2/lib/obj/food/seafood/
dw_fluffos_v2/lib/obj/food/vegetables/
dw_fluffos_v2/lib/obj/fungi/
dw_fluffos_v2/lib/obj/furnitures/artwork/
dw_fluffos_v2/lib/obj/furnitures/bathroom/
dw_fluffos_v2/lib/obj/furnitures/beds/
dw_fluffos_v2/lib/obj/furnitures/cabinets/
dw_fluffos_v2/lib/obj/furnitures/chairs/
dw_fluffos_v2/lib/obj/furnitures/chests/
dw_fluffos_v2/lib/obj/furnitures/clocks/
dw_fluffos_v2/lib/obj/furnitures/crockery/
dw_fluffos_v2/lib/obj/furnitures/cupboards/
dw_fluffos_v2/lib/obj/furnitures/cushions/
dw_fluffos_v2/lib/obj/furnitures/fake_plants/
dw_fluffos_v2/lib/obj/furnitures/lamps/
dw_fluffos_v2/lib/obj/furnitures/mirrors/
dw_fluffos_v2/lib/obj/furnitures/outdoor/
dw_fluffos_v2/lib/obj/furnitures/safes/
dw_fluffos_v2/lib/obj/furnitures/shelves/
dw_fluffos_v2/lib/obj/furnitures/sideboards/
dw_fluffos_v2/lib/obj/furnitures/sofas/
dw_fluffos_v2/lib/obj/furnitures/stoves/
dw_fluffos_v2/lib/obj/furnitures/tables/
dw_fluffos_v2/lib/obj/furnitures/wardrobes/
dw_fluffos_v2/lib/obj/handlers/
dw_fluffos_v2/lib/obj/handlers/autodoc/
dw_fluffos_v2/lib/obj/jewellery/anklets/
dw_fluffos_v2/lib/obj/jewellery/bracelets/
dw_fluffos_v2/lib/obj/jewellery/earrings/
dw_fluffos_v2/lib/obj/jewellery/misc/
dw_fluffos_v2/lib/obj/jewellery/necklaces/
dw_fluffos_v2/lib/obj/jewellery/rings/
dw_fluffos_v2/lib/obj/media/
dw_fluffos_v2/lib/obj/misc/buckets/
dw_fluffos_v2/lib/obj/misc/jars/
dw_fluffos_v2/lib/obj/misc/papers/
dw_fluffos_v2/lib/obj/misc/player_shop/
dw_fluffos_v2/lib/obj/misc/shops/
dw_fluffos_v2/lib/obj/misc/traps/
dw_fluffos_v2/lib/obj/monster/
dw_fluffos_v2/lib/obj/monster/godmother/
dw_fluffos_v2/lib/obj/monster/transport/
dw_fluffos_v2/lib/obj/plants/inherit/
dw_fluffos_v2/lib/obj/potions/
dw_fluffos_v2/lib/open/boards/
dw_fluffos_v2/lib/save/autodoc/
dw_fluffos_v2/lib/save/bank_accounts/
dw_fluffos_v2/lib/save/boards/frog/
dw_fluffos_v2/lib/save/books/bed_catalog/
dw_fluffos_v2/lib/save/creators/
dw_fluffos_v2/lib/save/mail/
dw_fluffos_v2/lib/save/mail/p/
dw_fluffos_v2/lib/save/soul/data/
dw_fluffos_v2/lib/save/tasks/
dw_fluffos_v2/lib/save/vaults/
dw_fluffos_v2/lib/secure/cmds/lord/
dw_fluffos_v2/lib/secure/config/
dw_fluffos_v2/lib/secure/items/
dw_fluffos_v2/lib/secure/player/
dw_fluffos_v2/lib/soul/
dw_fluffos_v2/lib/soul/i/
dw_fluffos_v2/lib/soul/j/
dw_fluffos_v2/lib/soul/k/
dw_fluffos_v2/lib/soul/o/
dw_fluffos_v2/lib/soul/q/
dw_fluffos_v2/lib/soul/to_approve/
dw_fluffos_v2/lib/soul/u/
dw_fluffos_v2/lib/soul/v/
dw_fluffos_v2/lib/soul/wish_list/
dw_fluffos_v2/lib/soul/y/
dw_fluffos_v2/lib/soul/z/
dw_fluffos_v2/lib/std/creator/
dw_fluffos_v2/lib/std/effects/
dw_fluffos_v2/lib/std/effects/attached/
dw_fluffos_v2/lib/std/effects/external/
dw_fluffos_v2/lib/std/effects/fighting/
dw_fluffos_v2/lib/std/effects/other/
dw_fluffos_v2/lib/std/environ/
dw_fluffos_v2/lib/std/guilds/
dw_fluffos_v2/lib/std/hospital/
dw_fluffos_v2/lib/std/house/
dw_fluffos_v2/lib/std/house/onebedhouse/
dw_fluffos_v2/lib/std/house/onebedhut/
dw_fluffos_v2/lib/std/house/tworoomflat/
dw_fluffos_v2/lib/std/languages/
dw_fluffos_v2/lib/std/liquids/
dw_fluffos_v2/lib/std/nationality/
dw_fluffos_v2/lib/std/nationality/accents/
dw_fluffos_v2/lib/std/nationality/accents/national/
dw_fluffos_v2/lib/std/nationality/accents/regional/
dw_fluffos_v2/lib/std/npc/goals/
dw_fluffos_v2/lib/std/npc/goals/basic/
dw_fluffos_v2/lib/std/npc/goals/misc/
dw_fluffos_v2/lib/std/npc/inherit/
dw_fluffos_v2/lib/std/npc/plans/
dw_fluffos_v2/lib/std/npc/plans/basic/
dw_fluffos_v2/lib/std/outsides/
dw_fluffos_v2/lib/std/races/shadows/
dw_fluffos_v2/lib/std/room/basic/topography/
dw_fluffos_v2/lib/std/room/controller/
dw_fluffos_v2/lib/std/room/controller/topography/
dw_fluffos_v2/lib/std/room/furniture/games/
dw_fluffos_v2/lib/std/room/furniture/inherit/
dw_fluffos_v2/lib/std/room/inherit/carriage/
dw_fluffos_v2/lib/std/room/inherit/topography/
dw_fluffos_v2/lib/std/room/punishments/
dw_fluffos_v2/lib/std/room/topography/area/
dw_fluffos_v2/lib/std/room/topography/iroom/
dw_fluffos_v2/lib/std/room/topography/milestone/
dw_fluffos_v2/lib/std/shadows/
dw_fluffos_v2/lib/std/shadows/attached/
dw_fluffos_v2/lib/std/shadows/curses/
dw_fluffos_v2/lib/std/shadows/disease/
dw_fluffos_v2/lib/std/shadows/fighting/
dw_fluffos_v2/lib/std/shadows/room/
dw_fluffos_v2/lib/std/shops/controllers/
dw_fluffos_v2/lib/std/shops/objs/
dw_fluffos_v2/lib/std/shops/player_shop/
dw_fluffos_v2/lib/std/shops/player_shop/office_code/
dw_fluffos_v2/lib/std/socket/
dw_fluffos_v2/lib/www/
dw_fluffos_v2/lib/www/external/autodoc/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/images/
dw_fluffos_v2/lib/www/external/java/telnet/examples/
dw_fluffos_v2/lib/www/external/java/telnet/tools/
dw_fluffos_v2/lib/www/pics/
dw_fluffos_v2/lib/www/secure/creator/
dw_fluffos_v2/lib/www/secure/editors/
dw_fluffos_v2/lib/www/secure/survey_results/
dw_fluffos_v2/win32/
/**
 * This is the system for case control.  It keeps tracks of all the current
 * open cases in the area and any modifications that are done to them.
 * @author Pinkfish
 * @started Tue Jul 11 18:09:01 PDT 2000
 */
#define NOMIC_SYSTEM_NO_CLASSES
#define NOMIC_SYSTEM_CASE_CLASSES
#include <nomic_system.h>

private mapping _open_cases;
private mapping _recently_closed_cases;
private mapping _closed_cases;
private int _next_case_id;
private int _next_note_id;

void save_me();
void send_council_inform(string area, int only_magistrates,
                         string mess);

void create() {
   _open_cases = ([ ]);
   _closed_cases = ([ ]);
   _recently_closed_cases = ([ ]);
   _next_case_id = 1;
   _next_note_id = 1;
} /* create() */

/**
 * This method creates an area.
 * @param area the name of the area to create
 */
void create_area(string area) {
   if (_open_cases[area]) {
      return ;
   }
   _open_cases[area] = ({ });
   _closed_cases[area] = ({ });
   _recently_closed_cases[area] = ({ });
} /* create_area() */

/**
 * This returns the cases which are currently open.
 * @param area the are to get the cases in
 * @return the list of opened cases
 */
int* query_open_cases(string area) {
   return _open_cases[area];
} /* query_open_cases() */

/**
 * This method returns the cases which are currently closed.
 * @param area the area to get the cases in
 * @return the list of closed cases
 */
int* query_closed_cases(string area) {
   return _closed_cases[area];
} /* query_closed_cases() */

/**
 * This method returns the set of recently closed cases.  These are
 * cases that can be appealed.
 * @param area the area to get the cases in
 * @return the list of recently closed cases
 */
int* query_recently_closed_cases(string area) {
   return _recently_closed_cases[area];
} /* query_recently_closed_cases() */

/**
 * This method returns the file name for the case given the id.
 * @param id the id to return
 * @return the file name
 */
string query_case_file_name(int id) {
   return NOMIC_CASE_SAVE + sprintf("cases/%02d/%d_case", id % 20, id);
} /* query_case_file_name() */

/**
 * This method finds the next case id.
 * @return the next case id
 */
int query_next_case_id() {
   int next;

   do {
      next = _next_case_id++;
   } while (sizeof(stat(query_case_file_name(next))));
   return next;
} /* query_next_case_id() */

private void save_case(class nomic_case stuff) {
   string fname;
   string tmp;

   fname = query_case_file_name(stuff->id);
   tmp = save_variable(stuff);
   unguarded((: write_file($(fname), $(tmp), 1) :));
} /* save_case() */

/**
 * This method returns the file name for the note given the id.
 * @param id the id to return
 * @return the file name
 */
string query_note_file_name(int id) {
   return NOMIC_CASE_SAVE + sprintf("notes/%02d/%d_note", id % 20, id);
} /* query_note_file_name() */

/**
 * This method finds the next note id.
 * @return the next note id
 */
int query_next_note_id() {
   int next;

   do {
      next = _next_note_id++;
   } while (sizeof(stat(query_note_file_name(next))));
   return next;
} /* query_next_note_id() */

private void save_note(class nomic_case_note stuff) {
   string fname;
   string tmp;

   fname = query_note_file_name(stuff->id);
   tmp = save_variable(stuff);
   unguarded((: write_file($(fname), $(tmp) ) :));
} /* save_note() */

private int create_case(string opener, string short, string* people) {
   class nomic_case new_case;

   new_case = new(class nomic_case);
   new_case->id = query_next_case_id();
   new_case->opener = opener;
   new_case->short = short;
   new_case->people = people;
   new_case->notes = ({ });
   new_case->events = ({ });
   new_case->time_opened = time();
   save_case(new_case);
   return new_case->id;
} /* create_case() */

private int create_note(string person, string text) {
   class nomic_case_note new_note;

   new_note = new(class nomic_case_note);
   new_note->id = query_next_note_id();
   new_note->person = person;
   new_note->text = text;
   new_note->time_created = time();
   save_note(new_note);
   return new_note->id;
} /* create_note() */

private class nomic_case_event create_event(int type, string person,
                                            string mess, mixed data) {
   class nomic_case_event event;

   event = new(class nomic_case_event);
   event->type = type;
   event->mess = mess;
   event->person = person;
   event->event_time = time();
   event->data = data;
   return event;
} /* create_event() */

/**
 * This method returns the short name of the event type.
 * @param type the type to find the name of
 * @return the name of the type
 */
string query_event_name(int type) {
   switch (type) {
   case NOMIC_CASE_EVENT_CLOSE :
      return "closed case";
   case NOMIC_CASE_EVENT_APPEAL :
      return "appealed case";
   case NOMIC_CASE_EVENT_ADD_PERSON :
      return "add person";
   case NOMIC_CASE_EVENT_REMOVE_PERSON :
      return "remove person";
   default :
      return "unknown";
   }
} /* query_event_name() */

/**
 * This method returns the case associated with the specified open
 * case.
 * @param area the area to look for the case in
 * @param id the id of the case
 * @return the case class
 */
class nomic_case query_open_case(string area, int id) {
   string fname;
   string tmp;

   if (!_open_cases[area]) {
      return 0;
   }

   if (member_array(id, _open_cases[area]) == -1) {
      return 0;
   }

   fname = query_case_file_name(id);
   tmp = unguarded((: read_file($(fname)) :));
   if (tmp) {
      return restore_variable(tmp);
   }
   return 0;
} /* query_open_case() */

/**
 * This method returns the case associated with the specified recently
 * closed case.
 * @param area the area to look for the case in
 * @param id the id of the case
 * @return the case class
 */
class nomic_case query_recently_closed_case(string area, int id) {
   string fname;
   string tmp;

   if (!_recently_closed_cases[area]) {
      return 0;
   }

   if (member_array(id, _recently_closed_cases[area]) == -1) {
      return 0;
   }

   fname = query_case_file_name(id);
   tmp = unguarded((: read_file($(fname)) :));
   if (tmp) {
      return restore_variable(tmp);
   }
   return 0;
} /* query_closed_case() */

/**
 * This method returns the case associated with the specified closed
 * case.
 * @param area the area to look for the case in
 * @param id the id of the case
 * @return the case class
 */
class nomic_case query_closed_case(string area, int id) {
   string fname;
   string tmp;

   if (!_closed_cases[area]) {
      return 0;
   }

   if (member_array(id, _closed_cases[area]) == -1) {
      return 0;
   }

   fname = query_case_file_name(id);
   tmp = unguarded((: read_file($(fname)) :));
   if (tmp) {
      return restore_variable(tmp);
   }
   return 0;
} /* query_closed_case() */

/**
 * This method return the exciting note associated with the case.
 * @param note_num the number of the note
 * @return the note class, or 0 on failure
 */
class nomic_case_note query_note(int note_num) {
   string fname;
   string tmp;

   fname = query_note_file_name(note_num);
   tmp = unguarded((: read_file($(fname)) :));
   if (tmp) {
      return restore_variable(tmp);
   }
   return 0;
} /* query_note() */

/**
 * This method opens a new case.
 * @param area the area the case is in
 * @param opener the person who opened it
 * @param short the short description of the case
 * @param people the people involved
 * @return 0 on failure and teh case id on success
 */
int add_new_case(string area, string opener, string short, string* people) {
   int case_id;

   if (!_open_cases[area]) {
      return 0;
   }
   case_id = create_case(opener, short, people);
   _open_cases[area] += ({ case_id });

   save_me();

   send_council_inform(area, 1, opener + " opened a case with " +
                      query_multiple_short(people));
   return case_id;
} /* add_new_case() */

/**
 * This method closes the case.
 * @param area the area the case is in
 * @param id the id of the case to close
 * @param closer the person that closes the case
 * @param result the string saying what the result of the case is
 * @param desc the description of the close reason
 * @param data special internal data used specifically for appeals
 * @return 1 on success, 0 on failure
 */
int close_case(string area, int id, string closer, string result,
               mixed data) {
   class nomic_case the_case;
   class nomic_case_event event;

   the_case = query_open_case(area, id);
   if (!the_case || !stringp(result)) {
      return 0;
   }

   event = create_event(NOMIC_CASE_EVENT_CLOSE, closer, result, data);
   the_case->events += ({ event });
   save_case(the_case);
   _open_cases[area] -= ({ the_case->id });
   _recently_closed_cases[area] += ({ the_case->id });
   save_me();
   send_council_inform(area, 1, closer + " closed a case with " +
                      query_multiple_short(the_case->people));
   return 1;
} /* close_case() */

/**
 * This method sets the case as reopened for an appeal.  After an appeal
 * the case will be closed again.
 * @param area the area the case is in
 * @param id the of the case to appeal
 * @param appealer the person who does the appeal
 * @param reason the reason for the appeal
 * @return 1 on success, 0 on failure
 */
int appeal_case(string area, int id, string appealer, string reason) {
   class nomic_case the_case;
   class nomic_case_event event;

   the_case = query_recently_closed_case(area, id);
   if (!the_case || !stringp(reason)) {
      return 0;
   }

   event = create_event(NOMIC_CASE_EVENT_APPEAL, appealer, reason, 0);
   the_case->events += ({ event });
   save_case(the_case);
   _recently_closed_cases[area] -= ({ the_case->id });
   _open_cases[area] += ({ the_case->id });
   save_me();
   send_council_inform(area, 1, appealer + " appeals a case with " +
                      query_multiple_short(the_case->people));
   return 1;
} /* appeal_case() */

/**
 * This method adds a note to the case.
 * @param area the area to get the case in
 * @param id the id of the case
 * @param person the person adding the note
 * @param text the actual note text
 * @return 1 on success, 0 on failure
 */
int add_note_to_case(string area, int id, string person, string text) {
   class nomic_case the_case;
   int note_id;

   the_case = query_open_case(area, id);
   if (!the_case) {
      return 0;
   }

   note_id = create_note(person, text);
   the_case->notes += ({ note_id });
   save_case(the_case);
   save_me();
   return 1;
} /* add_note_to_case() */

/**
 * This method adds a person to the case.
 * @param area the area the case is in
 * @param id the id of the case
 * @param adder the person that adds the person
 * @param person the person to be added to the case
 * @param text the reason for adding the person
 * @return 1 on success, 0 on failure
 */
int add_person_to_case(string area, int id, string adder, 
                       string person, string text) {
   class nomic_case the_case;
   class nomic_case_event event;

   the_case = query_open_case(area, id);
   if (!the_case || !stringp(text) ||
       member_array(person, the_case->people) != -1) {
      return 0;
   }

   event = create_event(NOMIC_CASE_EVENT_ADD_PERSON, adder, text, 0);
   the_case->events += ({ event });
   the_case->people += ({ person });
   save_case(the_case);
   return 1;
} /* add_person_to_case() */

/**
 * This method removes a person from the case.
 * @param area the area the case is in
 * @param id the id of the case
 * @param remover the person that removes the person
 * @param person the person to be removed to the case
 * @param text the reason for removeing the person
 * @return 1 on success, 0 on failure
 */
int remove_person_from_case(string area, int id, string remover, 
                       string person, string text) {
   class nomic_case the_case;
   class nomic_case_event event;

   the_case = query_open_case(area, id);
   if (!the_case || !stringp(text) ||
       member_array(person, the_case->people) == -1) {
      return 0;
   }

   event = create_event(NOMIC_CASE_EVENT_REMOVE_PERSON, remover, text, 0);
   the_case->events += ({ event });
   the_case->people -= ({ person });
   save_case(the_case);
   return 1;
} /* remove_person_to_case() */

/**
 * This method goes through and checks the recently closed cases to see
 * if any of them need to be moved to the closed set.
 */
void update_recently_closed_cases() {
   string area;
   int* stuff;
   int id;
   class nomic_case the_case;
   class nomic_case_event event;
   int last_close;

   foreach (area, stuff in _recently_closed_cases) {
      foreach (id in stuff) {
         the_case = query_recently_closed_case(area, id);
         last_close = 0;
         foreach (event in the_case->events) {
            if (event->type == NOMIC_CASE_EVENT_CLOSE) {
               last_close = event->event_time;
            }
         }
         if (last_close < time() - NOMIC_CASE_APPEAL_TIME) {
            //
            // Ok, move the case into the really closed bunch.
            //
            _closed_cases[area] += ({ id });
            _recently_closed_cases[area] -= ({ id });
         }
      }
   }
} /* update_recently_closed_cases() */