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 file used to do elections for magistrate positions.
 * @author Pinkfish
 * @started Mon Oct 23 22:30:19 PDT 2000
 */
inherit "/obj/handlers/inherit/citizens";

#include <player_handler.h>
#include <player.h>
#include <board.h>
#define NOMIC_SYSTEM_NO_CLASSES
#include <nomic_system.h>

#define CITIZEN_ELECTION_PHASE_NONE       0
#define CITIZEN_ELECTION_PHASE_NOMINATION 1
#define CITIZEN_ELECTION_PHASE_ELECTION   2
#define CITIZEN_ELECTION_PHASE_GRACE      3
#define CITIZEN_ELECTION_PHASE_DISABLED 4

#define CITIZEN_ELECTION_TIME   (20 * (7 * 24 * 60 * 60))
#define CITIZEN_ELECTION_PHASE_TIME      (10 * 24 * 60 * 60)
#define CITIZEN_PHASE_TIME      (14 * 24 * 60 * 60)
#define CITIZEN_GRACE_TIME      (14 * 24 * 60 * 60)
#define CITIZEN_ELECTION_DISABLED_TIME (14 * 24 * 60 * 60)

class election_data {
   int last_election;
   int phase;
   int phase_start;
   mapping nominations;
   mapping votes;
   string* voted;
}

protected void finish_election_phase(string area);
int post_citizen_message(string area, string subject, string message);

private mapping _elections;
private mapping _boards;

void create() {
   _elections = ([ ]);
   _boards = ([ ]);
   citizens::create();
   call_out("do_next_event", 10);
} /* create() */

/** @ignore yes */
void create_area(string area) {
   _elections[area] = new(class election_data);
   _elections[area]->phase = CITIZEN_ELECTION_PHASE_GRACE;
   _elections[area]->phase_start = time();
   _elections[area]->nominations = ([ ]);
   _elections[area]->votes = ([ ]);
   _elections[area]->voted = ({ });
   ::create_area(area);
} /* create_area() */

/**
 * This method returns the time of the next election.
 * @return the time of the next election, 0 if on is in progress
 */
int query_next_election_time(string area) {
   if (!_elections[area]) {
      return 0;
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_GRACE) {
      return _elections[area]->phase_start + CITIZEN_GRACE_TIME;
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_NONE) {
      return _elections[area]->last_election + CITIZEN_ELECTION_TIME;
   }
   return 0;
} /* query_next_election_time() */

/**
 * This method returns the end of the phase time.
 * @return the end of the phase time, 0 on failure
 */
int query_end_of_phase_time(string area) {
   if (!_elections[area]) {
      return 0;
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_NONE) {
      return 0;
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_ELECTION) {
      return _elections[area]->phase_start + CITIZEN_ELECTION_PHASE_TIME;
   }

   return _elections[area]->phase_start + CITIZEN_PHASE_TIME;
} /* query_end_of_phase_time() */

/**
 * This method returns the phase of the election.
 * @param area the area to check
 * @return the election phase
 */
protected int query_election_phase(string area) {
   if (!_elections[area]) {
      return CITIZEN_ELECTION_PHASE_NONE;
   }
   return _elections[area]->phase;
} /* query_election_phase() */

/**
 * This method checks to see if we are in the nomination phase.
 * @param area the area to check
 * @return 1 if we are, 0 if not
 */
int is_nomination_phase(string area) {
   return query_election_phase(area) == CITIZEN_ELECTION_PHASE_NOMINATION;
} /* is_nomination_phase() */

/**
 * This method checks to see if we are in the election phase.
 * @param area the area to check
 * @return 1 if we are, 0 if not
 */
int is_election_phase(string area) {
   return query_election_phase(area) == CITIZEN_ELECTION_PHASE_ELECTION;
} /* is_election_phase() */

/**
 * This method checks to see if we are in the grace phase.
 * @param area the area to check
 * @return 1 if we are, 0 if not
 */
int is_grace_phase(string area) {
   return query_election_phase(area) == CITIZEN_ELECTION_PHASE_GRACE;
} /* is_grace_phase() */

/**
 * This method nominates a person for a position.
 * @param area the area to nominate in
 * @param person the being nominated
 * @param nominator the person doing the nomination
 * @return 1 on success, 0 on failure
 */
int nominate_magistrate(string area, string person, string nominator) {
   if (!_elections[area] ||
       !is_citizen_of(area, person) ||
       !is_citizen_of(area, nominator)) {
      return 0;
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_NOMINATION) {
      if (!_elections[area]->nominations[person]) {
         _elections[area]->nominations[person] = ({ });
      } else if (member_array(nominator,
                              _elections[area]->nominations[person]) != -1) {
         return 0;
      }
      _elections[area]->nominations[person] += ({ nominator });
      save_me();
      return 1;
   }

   return 0;
} /* nominate_magistrate() */

/**
 * This method checks to see who has nominated a specified person.
 * @param area the area to check
 * @param person the person to check
 * @return the array of people who have nominated the person
 */
string* query_nominated_by(string area, string person) {
   if (!_elections[area]) {
      return ({ });
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_NOMINATION) {
      if (_elections[area]->nominations[person]) {
         return copy(_elections[area]->nominations[person]);
      }
   }

   return ({ });
} /* query_nominated_by() */

/**
 * This method returns the list of people who have been nominated.
 * @param area the area to get the list of people who are nominated
 * @return the list of people who have been nominated
 */
string* query_people_nominated(string area) {
   if (!_elections[area]) {
      return ({ });
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_NOMINATION) {
      return keys(_elections[area]->nominations);
   }

   return ({ });
} /* query_people_nominate() */

/**
 * This method checks to see if the specifiedf person has accepted their
 * nomination or not.
 * @param area the area to check in
 * @param person the person to check to see if they have accepted
 * @return 1 if they are accepted, 0 if not
 */
int is_nomination_accepted(string area, string person) {
   string* nominations;

   nominations = query_nominated_by(area, person);
   if (sizeof(nominations) >= 2 &&
       member_array(person, nominations) != -1) {
      return 1;
   }
   return 0;
} /* is_nomination_accepted() */

/**
 * This method checks to see if the specified person has voted.
 * @param area the area to check in
 * @param person the person the check
 * @return 1 if they have voted, 0 if not
 */
int has_voted(string area, string person) {
   if (!_elections[area]) {
      return 0;
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_ELECTION) {
      return member_array(person, _elections[area]->voted) != -1;
   }
   return 0;
} /* has_voted() */

/**
 * This method checks to see if the specified person is an eligible
 * person to vote for.
 * @param area the area to checlk
 * @param person the person to check
 * @return 1 if they are, 0 if not
 */
int is_eligible_to_vote_for(string area, string person) {
   if (!_elections[area]) {
      return 0;
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_ELECTION) {
      return member_array(person, keys(_elections[area]->votes)) != -1;
   }

   return 0;
} /* is_eleigble_to_vote_for() */

/**
 * This method votes for a specified person in the area.
 * @param area the area to vote for someone in
 * @param person the person to vote for
 * @param voter the person voting
 * @return 1 on success, 0 on failure
 */
int vote_for_people(string area, string* people, string voter) {
   string person;

   if (!_elections[area] ||
       !is_citizen_of(area, voter)) {
      return 0;
   }

   foreach (person in people) {
      if (!is_citizen_of(area, person)) {
         return 0;
      }
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_ELECTION) {
      if (has_voted(area, voter)) {
         return 0;
      }

      foreach (person in people) {
         if (is_eligible_to_vote_for(area, person)) {
            _elections[area]->votes[person]++;
         }
      }
      _elections[area]->voted += ({ voter });
      save_me();
      return 1;
   }

   return 0;
} /* vote_for_people() */

/**
 * This method retuns the list of people that can be voted for.
 * @param area the area to check in
 * @return the array of people that can be voted for
 */
string* query_can_vote_for(string area) {
   if (!_elections[area]) {
      return ({ });
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_ELECTION) {
      return keys(_elections[area]->votes);
   }

   return ({ });
} /* query_can_vote_for() */

/**
 * This method starts the election.
 * @param area the area to do the election for
 */
protected void start_election(string area) {
   if (!_elections[area]) {
      return ;
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_NONE ||
       _elections[area]->phase == CITIZEN_ELECTION_PHASE_GRACE) {
      _elections[area]->votes = ([ ]);
      _elections[area]->voted = ({ });
      _elections[area]->nominations = ([ ]);
      _elections[area]->phase_start = time();
      _elections[area]->phase = CITIZEN_ELECTION_PHASE_NOMINATION;
      save_me();
      post_citizen_message(area, "Nomination phase has started.",
                           "Please go to your council offices and "
                           "nominate\nthe magistrates for office.\n");
   }
} /* start_election() */

/**
 * This method finishes the nomination phase.
 * @param area the area to finish the phase for
 */
protected void finish_nomination_phase(string area) {
   string person;
   string* nominators;

   if (!_elections[area]) {
      return ;
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_NOMINATION) {
      //
      // Ok, zip through and remove all badies, non-citizens or 
      // people that were not nominated enough.
      //
      _elections[area]->votes = ([ ]);
      _elections[area]->voted = ({ });
      foreach (person, nominators in _elections[area]->nominations) {
         if (is_citizen_of(area, person) &&
             is_nomination_accepted(area, person) &&
             !PLAYER_HANDLER->test_creator(person)) {
            _elections[area]->votes[person] = 0;
         }
      }
      _elections[area]->phase = CITIZEN_ELECTION_PHASE_ELECTION;
      _elections[area]->phase_start = time();
      _elections[area]->nominations = ([ ]);
      save_me();
      post_citizen_message(area, "Nomination phase finished.",
                           "The people nominated for election are:\n" +
                           implode(map(keys(_elections[area]->votes),
                                       (: "   " + $1 :)), "\n"));
      if (sizeof(keys(_elections[area]->votes)) <=
          query_number_of_magistrates(area)) {
          //
          // Turn them all into magistrates.
          //
          finish_election_phase(area);
      }
   }
 
} /* finish_nomination_phase() */

/**
 * This method finishes the election phase.
 * @param area the area to finish the phase for
 */
protected void finish_election_phase(string area) {
   string* voted;
   string* sorted_voted;
   string high_pk;
   string high_non_pk;
   string person;
   string results;
   int needed;
   int num;

   if (!_elections[area]) {
      return ;
   }

   if (_elections[area]->phase == CITIZEN_ELECTION_PHASE_ELECTION) {
      if (sizeof(keys(_elections[area]->votes)) <=
          query_number_of_magistrates(area)) {
         voted = sort_array(keys(_elections[area]->votes),
                            (: $3[$2] - $3[$1] :), _elections[area]->votes);
         sorted_voted = voted;
      } else {
         //
         // Sort the people in order of votes.
         //
         voted = sort_array(keys(_elections[area]->votes),
                            (: $3[$2] - $3[$1] :), _elections[area]->votes);
         sorted_voted = voted;

         //
         // Ok, see if we have one pk and one npk.
         //
         needed = query_number_of_magistrates(area);
         foreach (person in voted) {
            if (PLAYER_HANDLER->test_player_killer(person)) {
               if (!high_pk) {
                  needed--;
                  high_pk = person;
               }
            } else {
               if (!high_non_pk) {
                  needed--;
                  high_non_pk = person;
               }
            }
            if (high_pk && high_non_pk) {
               break;
            }
         }

         voted -= ({ high_pk, high_non_pk });
         voted = voted[0..needed - 1];
         voted += ({ high_pk, high_non_pk });
         voted -= ({ 0 });
      }
      //
      // Post the results.
      //
      results = "Votes:\n";
      foreach (person in sorted_voted) {
         results += sprintf("%20s %d\n", capitalize(person),
                            _elections[area]->votes[person]);
      }
      results += "\nElected officals are " + query_multiple_short(voted) + "\n";
      results += "\nNumber of people who voted " +
                 sizeof(_elections[area]->voted);
      num = query_number_of_citizens(area);
      if (num == 0) {
         results += " (100% of the citizens)\n";
      } else {
         results += " (" + (sizeof(_elections[area]->voted) * 100 / num) +
                    "% of the citizens)\n";
      }
      _elections[area]->votes = ([ ]);
      _elections[area]->voted = ({ });
      _elections[area]->phase = CITIZEN_ELECTION_PHASE_NONE;
      _elections[area]->phase_start = time();
      _elections[area]->last_election = time();
      _elections[area]->nominations = ([ ]);

      post_citizen_message(area, "Election results", results);

      setup_magistrates(area, voted);
      save_me();
   }
} /* finish_election_phase() */

/** @ignore yes */
protected void do_next_event() {
   int next_event;
   int time_to_next_event;
   string area;
   class election_data data;

   foreach (area, data in _elections) {
      switch (data->phase) {
      case CITIZEN_ELECTION_PHASE_NONE :
         next_event = (data->last_election - time()) + CITIZEN_ELECTION_TIME;
         if (next_event <= 0) {
            start_election(area);
         }
         break;
      case CITIZEN_ELECTION_PHASE_NOMINATION :
         next_event = (data->phase_start - time()) + CITIZEN_PHASE_TIME;
         if (next_event <= 0) {
            finish_nomination_phase(area);
         }
         break;
      case CITIZEN_ELECTION_PHASE_ELECTION :
         next_event = (data->phase_start - time()) + CITIZEN_ELECTION_PHASE_TIME;
         if (next_event <= 0) {
            finish_election_phase(area);
         }
         break;
      case CITIZEN_ELECTION_PHASE_GRACE :
         next_event = (data->phase_start - time()) + CITIZEN_GRACE_TIME;
         if (next_event <= 0) {
            start_election(area);
         }
         break;

      case CITIZEN_ELECTION_PHASE_DISABLED : 
         next_event = (data->phase_start - time()) + 
            CITIZEN_ELECTION_DISABLED_TIME;
         if (next_event <= 0) {
             /*  Because this phase is disabled, we're not going to do to
                 trigger any event here at all. */ 
             next_event = next_event;
         }
         break;
      }

      if (next_event > 0 &&
          (next_event < time_to_next_event || !time_to_next_event)) {
         time_to_next_event = next_event;
      }
   }
   if(time_to_next_event) {
     call_out("do_next_event", time_to_next_event);
   }
} /* do_next_event() */

/**
 * This method sets the board for the specified area.
 * @param area the area to set the board for
 * @param name the name of the board
 */
void set_citizen_board(string area, string name) {
   if (!pointerp(_boards[area])) {
      _boards[area] = ({ 0, 0 });
   }
   _boards[area][0] = name;
   save_me();
} /* set_citizen_board() */

/**
 * This method returns the board for the specified area.
 * @param area the area to look for the board on
 * @return the board name for the area, 0 for none
 */
string query_magistrate_board(string area) {
   if (pointerp(_boards[area])) {
      return _boards[area][1];
   }
   return 0;
} /* query_magistrate_board() */

/**
 * This method sets the board for the specified area.
 * @param area the area to set the board for
 * @param name the name of the board
 */
void set_magistrate_board(string area, string name) {
   if (!pointerp(_boards[area])) {
      _boards[area] = ({ 0, 0 });
   }
   _boards[area][1] = name;
   save_me();
} /* set_magistrate_board() */

/**
 * This method returns the board for the specified area.
 * @param area the area to look for the board on
 * @return the board name for the area, 0 for none
 */
string query_citizen_board(string area) {
   if (pointerp(_boards[area])) {
      return _boards[area][0];
   }
   return 0;
} /* query_citizen_board() */

/**
 * This method will post a message to the citizen board from the
 * administration.
 * @param area the area to post the message to 
 * @param subject the subject it has
 * @param message the message to post
 */
int post_citizen_message(string area, string subject, string message) {
   string board;

   board = query_citizen_board(area);
   if (board) {
      return BOARD_HAND->add_message(board,
                           NOMIC_SYSTEM_ADMINISTRATOR_NAME,
                           subject,
                           message);
   }
   return 0;
} /* post_citizen_message() */

/**
 * This method will post a message to the magistrate board from the
 * administration.
 * @param area the area to post the message to 
 * @param subject the subject it has
 * @param message the message to post
 */
int post_magistrate_message(string area, string subject, string message) {
   string board;

   board = query_magistrate_board(area);
   if (board) {
      return BOARD_HAND->add_message(board,
                           NOMIC_SYSTEM_ADMINISTRATOR_NAME,
                           subject,
                           message);
   }
   return 0;
} /* post_magistrate_message() */

/**
 * This method sets the specifed election to "disabled", meaning it will
 * sit indefinitely with no election.
 */
int disable_citizen_election(string area) {
    if (!_elections[area]) {
      return 0;
    }

   _elections[area]->phase = CITIZEN_ELECTION_PHASE_DISABLED;
   _elections[area]->phase_start = time();
   _elections[area]->nominations = ([ ]);
   _elections[area]->votes = ([ ]);
   _elections[area]->voted = ({ });
   save_me();
   return 1;
} /* disable_citizen_election() */