#include "mail.h"
inherit "/std/object";
#include "board.h"
string board_name;
mapping being_written;
void setup() {
  set_name("board");
  set_short("collection of scrolls");
  add_adjective("boards");
  reset_drop();
   reset_get();
  board_name = "fish";
  being_written = ([ ]);
}
string query_plural() {
  mixed *stuff;
  stuff = (mixed *)BOARD_HAND->get_subjects(board_name);
  switch (sizeof(stuff)) {
    case 0:  return pluralize(::short(0))+" [ Empty ]";
    case 1:  return pluralize(::short(0))+" [ 1 note ]";
  }
   return pluralize(::short(0))+" [ "+sizeof(stuff)+" notes ]";
}
string short(int dark) {
  mixed *stuff;
  stuff = (mixed *)BOARD_HAND->get_subjects(board_name);
  switch (sizeof(stuff)) {
    case 0:  return ::short(dark)+" [ Empty ]";
    case 1:  return ::short(dark)+" [ 1 note ]";
    default:
      return ::short(dark)+" [ "+sizeof(stuff)+" notes ]";
  }
}
string the_date(int i) {
  return ctime(i)[4..9];
}
string long(string str, int dark) {
  int i;
  mixed *stuff;
  string ret;
  mapping news_rc;
  stuff = (mixed *)BOARD_HAND->get_subjects(board_name);
  ret = "A collection of scrolls ("+board_name+").\n";
  ret += sprintf("%#-*s\n\n", this_player()->query_cols(),
                            "read <note number>\npost <subject>\n"+
                            "store <note number> <file>\neat <note number>\n"+
                            "reply <note number>\nfollowup <note number>\n"+
                            "summary [all]\nnext\nprev\nnew\nboard <board name>\n"+
                            "killfile <board name>");
  if (!sizeof(stuff))
    return ret+"The board is completely empty.\n";
  news_rc = (mapping)this_player()->query_property(NEWS_RC);
  if (!news_rc)
    news_rc = ([ ]);
  for (i=0;i<sizeof(stuff);i++)
    if (news_rc[board_name] < stuff[i][B_TIME])
      ret += sprintf("N %2d: %-=*s\n", i+1, (int)this_player()->query_cols()-6,
             stuff[i][B_SUBJECT]+" ("+
             capitalize(stuff[i][B_NAME])+" "+the_date(stuff[i][B_TIME])+")");
    else
      ret += sprintf("  %2d: %-=*s\n", i+1, (int)this_player()->query_cols()-6,
             stuff[i][B_SUBJECT]+" ("+
             capitalize(stuff[i][B_NAME])+" "+the_date(stuff[i][B_TIME])+")");
  return ret;
}
void init() {
  add_action("read", "read");
  add_action("post", "post");
  add_action("post", "note");
  add_action("eat", "eat");
  add_action("followup", "followup");
  add_action("reply", "reply");
  add_action("save_note", "store");
  add_action("next", "next");
  add_action("prev", "prev");
  add_action("new", "new");
  add_action("board", "board");
  add_action("kfile", "killfile");
  add_action("summary","summary");
}
void string_more(string arg, string prompt) {
  object obj;
/* changed to our more_string
  if (!(obj = (object)MAIL_SERVER->mail_reader(this_player()))) {
    log_file(LOG_FILE, "board: got NULL MAIL_READER from MAIL_SERVER.\n");
    write("MAIL_SERVER error ...\n");
    return;
  }
  obj->string_more(arg, prompt);
*/
  this_player()->set_finish_func(0);
  this_player()->more_string(arg, prompt);
}
int read(string str) {
  int num, i;
  mixed stuff;
  mapping news_rc;
  notify_fail("Syntax: read <note number>\n");
  stuff = (mixed *)BOARD_HAND->get_subjects(board_name);
  news_rc = (mapping)this_player()->query_property(NEWS_RC);
  if (!news_rc)
    news_rc = ([ ]);
  if (!str) {
    i = sizeof(stuff)-1;
    while (i >= 0 && stuff[i][B_TIME] > news_rc[board_name] )
      i--;
    while (i < sizeof(stuff)-1 &&
           this_player()->query_property("news_kill_"+
            lower_case(stuff[i+1][B_NAME]))) {
             i++;
    }
    if (i == sizeof(stuff)-1) {
      notify_fail("No unread messages.\n");
      return 0;
    }
    num = i+2;
  } else if (sscanf(str, "%d", num) != 1)
    return 0;
  if (num < 1 || num > sizeof(stuff)) {
    notify_fail("No note of that number.\n");
    return 0;
  }
  num --;
  if (news_rc[board_name] < stuff[num][B_TIME]) {
    news_rc[board_name] = stuff[num][B_TIME];
    this_player()->add_property(NEWS_RC, news_rc);
  }
  string_more(sprintf("Note #%d by %s posted at %s\nTitle: '%s'\n\n", 
              num+1, capitalize(stuff[num][B_NAME]), ctime(stuff[num][B_TIME]),
              stuff[num][B_SUBJECT][0..(int)this_player()->query_cols()-10])+
              BOARD_HAND->get_message(board_name, num),
                 "[Note "+(num+1)+"]");
/*
  string_more(sprintf("%|*s\n\n", this_player()->query_cols(),
              "Note #"+(num+1)+" on "+stuff[num][B_SUBJECT]+" by "+
              stuff[num][B_NAME])+
              BOARD_HAND->get_message(board_name, num),
                 "[Note "+(num+1)+"]");
 */
  return 1;
}
int post(string str) {
  string body;
  notify_fail("Syntax: post <subject>\n");
  if (!str)
    return 0;
/* ok shove the editing stuff in here.  Lets make it function string_edit
 * sound frogy?
 */
/*
  string_edit("");
  body = string_edit_res;
*/
  being_written[this_player()->query_name()] = str;
  this_player()->do_edit(0,"end_of_thing");
  return 1;
}
void end_of_thing(string body) {
  if (body && body != "" && being_written[this_player()->query_name()])
    if (!BOARD_HAND->add_message(board_name, this_player()->query_name(),
                            being_written[this_player()->query_name()], body))
      write("Error writing message.\n");
    else
      write("Message posted.\n");
  else
    write("Erorr.\n");
  being_written = m_delete(being_written, this_player()->query_name());
  return ;
}
int eat(string str) {
  int num;
  notify_fail("Syntax: read <note number>\n");
  if (!str)
    return 0;
  if (sscanf(str, "%d", num) != 1)
    return 0;
  if (!BOARD_HAND->delete_message(board_name, num-1))
    return 0;
  write("You viciously tear off and eat note "+num+"\n");
  say(this_player()->query_cap_name()+" viciously tears off and eats note "+
         num+".\n");
  return 1;
}
int followup(string str) {
  int num, i;
  mixed stuff;
  string s;
  notify_fail("Syntax: read <note number>\n");
  if (!str)
    return 0;
  if (sscanf(str, "%d", num) != 1)
    return 0;
  stuff = (mixed *)BOARD_HAND->get_subjects(board_name);
  if (num < 1 || num > sizeof(stuff)) {
    notify_fail("No note of that number.\n");
    return 0;
  }
  if (sscanf(stuff[num-1][B_SUBJECT], "Re:#%d %s", i, s) != 2)
    being_written[this_player()->query_name()] = "Re:#1 "+stuff[num-1][B_SUBJECT];
  else
    being_written[this_player()->query_name()] = "Re:#"+i+" "+s;
  this_player()->do_edit(0,"end_of_thing");
  return 1;
}
int reply(string str) {
  int num;
  mixed stuff;
  notify_fail("Syntax: read <note number>\n");
  if (!str)
    return 0;
  if (sscanf(str, "%d", num) != 1)
    return 0;
  stuff = (mixed *)BOARD_HAND->get_subjects(board_name);
  if (num < 1 || num > sizeof(stuff)) {
    notify_fail("No note of that number.\n");
    return 0;
  }
  MAIL_TRACK->mail(stuff[num-1][B_NAME], stuff[num-1][B_SUBJECT]);
  return 1;
}
int save_note(string arg) {
  int which;
  string file;
  mixed *stuff;
  if (!arg || (sscanf(arg, "%d %s", which, file) != 2)) {
    notify_fail("Syntax: store <note number> <file name>\n");
    return 0;
  }
  stuff = (mixed *)BOARD_HAND->get_subjects(board_name);
  if (which < 1 || which > sizeof(stuff)) {
    notify_fail("Invalid note number.\n");
    return 0;
  }
  which--; /* 1..n */
  file += ".note";
  if (!MASTER_OB->valid_write(file, this_player()->query_name())) {
    notify_fail("The master object appears and prevents you.\n");
    return 0;
  }
  write_file(file,stuff[which][B_SUBJECT]+"\n\n"+
             BOARD_HAND->get_message(board_name, which));
  write("Ok.\n");
  return 1;
}
void set_board_name(string str) { board_name = str; }
void set_datafile(string str) { board_name = str; }
int next() {
  int i;
  string *boards;
  boards = (string *)BOARD_HAND->list_of_boards();
  if ((i = member_array(board_name, boards)) == -1)
    i = 0;
  else
    i = (i+1)%sizeof(boards);
  board_name = boards[i];
  write("Gone to board:"+board_name+".\n");
  return 1;
}
int prev() {
  int i;
  string *boards;
  boards = (string *)BOARD_HAND->list_of_boards();
  if ((i = member_array(board_name, boards)) == -1)
    i = 0;
  else
    i = (i-1+sizeof(boards))%sizeof(boards);
  board_name = boards[i];
  write("Gone to board:"+board_name+".\n");
  return 1;
}
int kfile(string arg) {
  this_player()->add_property("news_kill_"+lower_case(arg),1);
  return 1;
}
int newx() {
  int i;
  string *boards;
  mixed *stuff;
  mixed otherstuff;
  mapping news_rc;
  boards = (string *)BOARD_HAND->list_of_boards();
/* start from the begining and search for one with new notes. */
  news_rc = (mapping)this_player()->query_property(NEWS_RC);
/* John's mark current board as read hack */
  otherstuff = (mixed *)BOARD_HAND->get_subjects(board_name);
  if (sizeof(otherstuff)) {
    news_rc[board_name] = otherstuff[sizeof(otherstuff)-1][B_TIME];
    this_player()->add_property(NEWS_RC, news_rc);
  }
/* */
  for (i=0;i<sizeof(boards);i++) {
    if (!this_player()->query_property("news_kill_"+boards[i])) {
      stuff = (mixed *)BOARD_HAND->get_subjects(boards[i]);
      if (!sizeof(stuff))
        continue;
      if (stuff[sizeof(stuff)-1][B_TIME] > news_rc[boards[i]]) {
        board_name = boards[i];
        write("The "+board_name+" board has new messages.\n");
        return 1;
      }
    }
  }
  notify_fail("No boards with new messages.\n");
  return 0;
}
int summary(string str) {
  int all,i,j,unred,numdone;
  string *boards;
  mixed *stuff;
  mapping news_rc;
  all=0;
  if (str) {
    if (str=="all") {
      all=1;
    } else {
      write("Usage: summary [all]\n");
      return 1;
    }
  }
  boards = (string *)BOARD_HAND->list_of_boards();
/* start from the begining and start listing them. */
  news_rc = (mapping)this_player()->query_property(NEWS_RC);
  numdone = 0;
  for (i=0;i<sizeof(boards);i++) {
    if (boards[i] && !this_player()->query_property("news_kill_"+boards[i])) {
      unred = 0;
      stuff = (mixed *)BOARD_HAND->get_subjects(boards[i]);
      for (j=sizeof(stuff);j && stuff[--j][B_TIME]>news_rc[boards[i]];unred++);
      /*stuff[sizeof(stuff)-1][B_TIME];*/
      if (unred || all) {
        printf("%-*s %d\n",(int)this_player()->query_cols()/2,boards[i],unred);
        numdone++;
      }
    }
  }
  if (!numdone) write("No unread messages anywhere.\n");
  return 1;
}
int board(string str) {
  int i;
  string *boards;
  if (!str) {
    notify_fail("Syntax: board <board name>\n");
    return 0;
  }
  boards = (string *)BOARD_HAND->list_of_boards();
  if ((i=member_array(str, boards)) == -1) {
    notify_fail("The board "+str+" does not exist sorry.\n");
    return 0;
  }
  write("Ok.\n");
  board_name = str;
  return 1;
}