/
lib/banish/
lib/d/
lib/doc/
lib/doc/domains/
lib/doc/efun/
lib/doc/examples/
lib/doc/examples/armour/
lib/doc/examples/contain/
lib/doc/examples/food/
lib/doc/examples/magic/
lib/doc/examples/monster/
lib/doc/examples/room/
lib/doc/examples/weapons/
lib/function/
lib/include/
lib/include/fn_specs/
lib/include/skills/
lib/info/
lib/inherit/base/
lib/log/
lib/manuals/312/
lib/news/
lib/obj/party/
lib/objects/components/
lib/open/
lib/open/library/
lib/open/party/
lib/players/
lib/players/zilanthius/
lib/room/
lib/room/city/arena/
lib/room/city/creator/
lib/room/city/garden/monst/
lib/room/city/obj/
lib/room/city/shop/
lib/room/death/
lib/room/registry/
lib/secure/
lib/secure/UDP_CMD_DIR/
lib/skills/
lib/skills/fighter/
lib/skills/thief/
lib/usr/
lib/usr/creators/
lib/usr/players/
/* Bulletin Board 2 */

/*
   This board gives the player greater control over notices. It uses 
   /obj/editor (a string editor), and /obj/pager (a 'more' for strings).
   These are also used by the mailer 
 */

#include <mudlib.h>
inherit BASE;

#include <ansi.h>

#define NAME    (string)this_player()->query_name()
#define REAL    (string)this_player()->query_name(1)
#define HEADER  0
#define AUTHOR  1
#define MESSAGE 2
#define TIME    ctime(time())[4..15]
#define PASTE   "/"+ PASTE_DIR +"/"+ REAL

/* bulletins */

mixed *bulletins;    /* ({ ({ header, author, message, }), }) */
static string save_file; 

/* new notice */

static object new_author;
static string new_header;
static int edit_old;

#ifdef NATIVE_MODE
void create() {
#else
void reset(status arg) {
  if(arg) return;
#endif /* native */
  set_name("bulletin board");
  set_alt_name("board");
  set_extra_long("There is a bulletin board here.\n");
  bulletins = ({});
}

 
void long(status wiz) { 
    int i;

    if(query_long()) ::long(wiz);
    write("You can set up new notes with the command 'note headline'.\n"); 
    write("Read a note with 'read num', and remove an old note(s) with\n"); 
    write("'remove num{,num2}'.  You can clip a note to your clipboard with\n"+
          "'clip num'. You can edit one of your old notes with\n"+
          "'edit num'.\n");
    if(!sizeof(bulletins)) {
      write("It is Empty.\n");
    }
    else if(sizeof(bulletins) == 1) {
      write("The Bulletin Board contains 1 note:\n\n");
    }
    else {
      write("The Bulletin Board contains "+ sizeof(bulletins) +" notes:\n\n");
    }
    say(NAME +" studies the bulletin board.\n"); 
    for(i = 0; i < sizeof(bulletins); i++) {
      write((i+1) +".\t"+ bulletins[i][HEADER] +"\n");
    }
} 
 
void set_save_file(string file) { 
  save_file = file; 
  if(save_file) restore_object(save_file); 
} 

 
status get() { 
  write("It is secured to the ground.\n"); 
  return 0; 
} 
 

init() { 
   if(!bulletins) bulletins = ({});
   add_action ("new", "note"); 
   add_action ("read", "read"); 
   add_action ("remove", "remove"); 
   add_action ("bo", "bo"); 
   add_action ("read", "clip");
   add_action ("edit", "edit");
} 


status bo() {
  long(0);
  return 1;
}

/*************************************************************************/


void add_message(string arg) {  /* quit and save from editor */
  if(new_author != this_player()) return;
  if(edit_old) { /* was editing old notice */
    bulletins = bulletins[0..(edit_old-2)]
              + bulletins[edit_old..(sizeof(bulletins)-1)];
    edit_old = 0;
  }
  bulletins += ({
                 ({
                   new_header,
                         REAL,
                          arg,
                 })
               });
  if(save_file) save_object(save_file);
  new_author = 0;
  new_header = 0;
}


void editor_quit(string arg) {  /* quit, no save from editor */
  edit_old = 0;
  new_author = 0;
  new_header = 0;
}


/***********************************************************************/
/* edit old notice */


status edit(string str) {
  int i;
  string rest;

  if(!str || !(sscanf(str, "%d", i) || sscanf(str, "note %d", i))) return 0; 
  if(i < 1 || i > sizeof(bulletins)) { 
    write("Not that number of messages.\n"); 
    return 1; 
  } 
  i -= 1;
  if(!this_player()->id(bulletins[i][AUTHOR])) {
    write("Sorry, you can only edit your own notice.\n");
    return 1;
  }
  if(new_author && environment(new_author) == environment()) {
    write((string)new_author->query_name() +" is busy writing.\n"); 
    return 1; 
  } 
  sscanf(bulletins[i][HEADER],"%s("+capitalize(REAL)+", %s",new_header,rest);
  new_header += "("+capitalize(REAL) +", "+ TIME +")";
  new_author = this_player();
  edit_old = i + 1;
  clone_object(EDITOR)->edit("add_message",bulletins[i][MESSAGE],1);
  return 1;
}


/*************************************************************************/
/* add new notice */

status new(string hd) { 
  if(!hd) {
    notify_fail("You must give a title.\n");
    return 0; 
  }
  if(new_author && environment(new_author) == environment()) {
    write((string)new_author->query_name() +" is busy writing.\n"); 
    return 1; 
  } 
  if(sizeof(bulletins) == 30) { 
    write("You have to remove an old message first.\n"); 
    return 1; 
  } 
  if(strlen(hd) > 50) { 
    write("Too long header to fit the paper.\n"); 
    return 1; 
  } 
  hd = (string)this_player()->filter_ansi(hd); /* all headers filtered */
  new_author = this_player();  
  new_header = hd +"("+ capitalize(REAL) +", "+ TIME +")";
  clone_object(EDITOR)->edit("add_message",0,1);
  return 1; 
} 

/**************************************************************************/
/* read notice */

status read(string str) { 
  int i, k; 
  object pager_ob; 

  if(!str || (sscanf(str, "%d", i) && sscanf(str, "note %d", i))) { 
    if(query_verb() == "clip") 
      notify_fail("Usage: clip <note number>\n");
    return 0;
  }
  if(i < 1 || i > sizeof(bulletins)) { 
    write("Not that number of messages.\n"); 
    return 1; 
  }
  i -= 1;
  say(NAME +" reads a note titled '"+ bulletins[i][HEADER] +"'.\n"); 
  if(query_verb() == "clip") {
    str = bulletins[i][MESSAGE];
  }
  else if(this_player()->ansi_on()) {
    str = bulletins[i][MESSAGE] + OFF;
  }
  else {
    str = (string)this_player()->filter_ansi(bulletins[i][MESSAGE]);
  }
  if(query_verb() == "clip") {
    rm(PASTE);
    write("The note is titled '" + bulletins[i][HEADER] + 
          "' has been copied to your Clipboard.\n"); 
    write_file(PASTE, str);
  }
  else {
    write("The note is titled '" + bulletins[i][HEADER] + "':\n\n"); 
#ifdef PAGER
    pager_ob = clone_object(PAGER);
#ifdef NATIVE_MODE
    pager_ob->move(this_player());
#else
    move_object(pager_ob, this_player());
#endif /* NATIVE_MODE */
    pager_ob->page(str);
#else
    write(str); 
#endif
  }
  return 1; 
} 
 

status remove(string str) { 
  int i, j, k; 
 
  if(!str || !(sscanf(str, "%d,%d", i, j) || sscanf(str, "note %d", i)
  || sscanf(str, "%d", i))) {
    notify_fail("remove <number>\nremove <number1,number2>\n");
    return 0; 
  }
  if(i < 1 || i > sizeof(bulletins)) { 
    notify_fail("Not that number of messages.\n"); 
    return 0; 
  }
  if(j < i) j = i;
  if(j > sizeof(bulletins)) j = sizeof(bulletins);
  for(i -= 1, j -= 1; j >= i; j--) {
    if(!(this_player()->id(bulletins[j][AUTHOR]) ||
         this_player()->query_security_level())) {
       write("Sorry, you will have to ask a creator to remove the message "+
             (j+1) +"for you.\n");
       continue;
    }
    say(NAME +" removed a note titled '"+ bulletins[j][HEADER] +"'.\n"); 
    write("You remove the note "+ bulletins[j][HEADER] +"...\n");
    bulletins = bulletins[0..j-1]+bulletins[j+1..sizeof(bulletins)-1];
  }
  if(save_file) save_object(save_file);
  return 1;
}