/
CDC-1.2b/
CDC-1.2b/src/
parent $mail_root
parent $mail_list
parent $user_interfaces
object $mail_ui

var $root child_index 0
var $root owners [$mail_ui]
var $root owned [$mail_ui]
var $root fertile 0
var $has_commands commands [["@m?ail * on *", 'mail_on_cmd], ["@mail-sub?scribe|@msub?scribe *", 'subscribe_cmd], ["@mail-unsub?scribe|@munsub?scribe *", 'unsubscribe_cmd], ["@mail-subscribed|@msubscribed", 'subscribed_cmd], ["@mail-r?ead|@mr?ead * on *", 'mail_read_cmd], ["@mail-rem?ove|@mrem?ove|@mrm * from|on *", 'mail_remove_cmd], ["@msend|@mmail * to *", 'send_note_cmd], ["@mail-lists", 'mail_lists_cmd]]
var $has_commands shortcuts [["@m?ail", 'mail_on_cmd, ["@mail", "", "on", "me"]]]
var $root inited 1
var $mail_ui subscribed #[]
var $mail_list letters #[]
var $mail_list letters_index #[]
var $mail_list senders 1
var $mail_list readers [$core]
var $mail_list notify [$mail_ui]
var $mail_list last_letter 0
var $gendered gender $gender_neuter
var $described prose #[]
var $root manager $mail_ui
var $root writable [$mail_ui]
var $root readable ['parameters, 'methods, 'code]
var $root dbref 'mail_ui
var $old_command_environment verb_cache #[]
var $old_command_environment command_cache []
var $old_command_environment shortcuts_cache []
var $named name ['prop, "Mail User Interface"]
var $mail_list mail []
var $mail_ui current 0

method send_note_cmd
    arg cmd, note, prep, line;
    var subj, lists, list, x, mail;
    
    (> .perms(sender(), 'this) <);
    note = .match_env_nice(note);
    line = line.explode_english_list();
    lists = [];
    for x in (line) {
        catch ~listnf {
            list = $mail_utils.match_mail_recipient(x);
            lists = [@lists, list];
        } with handler {
            .tell(("The list \"" + x) + "\" is invalid.");
        }
    }
    if (!lists) {
        .tell("No valid lists are specified!");
        return;
    }
    subj = .prompt("Subject: ");
    if (subj == "@abort") {
        .tell("Aborted.");
        return;
    }
    mail = $mail.new_mail();
    mail.set_subject(subj);
    mail.set_text(note.text());
    catch any {
        mail.send(@lists);
    } with handler {
        .tell((traceback()[1])[2]);
    }
    .tell("Mail sent.");
.

method mail_read_cmd
    arg cmd, rng, on, list;
    var mail, x, lname;
    
    (> .perms(sender(), 'this) <);
    list = $mail_utils.match_mail_recipient(list || "me");
    .new_list(list);
    if (rng) {
        if (rng == "next") {
            if (!(current['location]))
                .tell("No next message.");
            else
                .read_mail(list.next(current['location]));
            return;
        }
        catch ~range {
            rng = $mail_utils.range_to_actual($parse.range(rng), current);
        } with handler {
            .tell((traceback()[1])[2]);
            return;
        }
    }
    mail = list.mail();
    lname = list.mail_name();
    if (rng) {
        for x in [rng[1] .. rng[2]] {
            if (x > listlen(mail))
                break;
            .read_mail(mail[x], lname);
        }
    } else if (current['location]) {
        .read_mail(current['location], lname);
    } else {
        .tell(("List " + lname) + " has no mail on it.");
    }
.

method mail_remove_cmd
    arg cmd, rng, from, list;
    var mail, all_mail, x, name;
    
    (> .perms(sender(), 'this) <);
    list = $mail_utils.match_mail_recipient(list || "me");
    .new_list(list);
    if (rng) {
        catch ~range {
            mail = (| $object.to_dbref(rng) |);
            if (!mail) {
                rng = $mail_utils.range_to_actual($parse.range(rng), current);
                all_mail = list.mail();
                mail = [];
                for x in [rng[1] .. rng[2]] {
                    if (x > listlen(all_mail))
                        break;
                    mail = [@mail, all_mail[x]];
                }
            } else {
                mail = [mail];
            }
        } with handler {
            .tell((traceback()[1])[2]);
            return;
        }
    }
    for x in (mail) {
        catch ~perm {
            name = x.name();
            list.del_mail(x);
            .tell(("Removed mail message " + name) + " from list.");
        } with handler {
            .tell((traceback()[1])[2]);
        }
    }
.

method read_mail
    arg mail, list_name;
    
    (> .perms(sender(), 'this) <);
    .tell(((("Message " + (mail.name())) + " on ") + list_name) + ":");
    .tell(mail.format());
    mail.did_read();
.

method subscribed
    (> .perms(sender(), 'this) <);
    return subscribed;
.

method subscribed_cmd
    arg cmd;
    var l, line;
    
    (> .perms(sender(), 'this) <);
    for l in (subscribed.keys()) {
        if (l == this())
            continue;
        line = ("  " + (l.mail_name())) + " ";
        if ((l.last_received_on()) > (subscribed[l]))
            line = line + " (new mail)";
        else
            line = line + " (no new mail)";
        .tell(line);
    }
.

method unsubscribe_cmd
    arg com, str;
    var list, line, mname;
    
    (> .perms(sender(), 'this) <);
    list = .match_mail_recipient(str);
    if (list == this())
        return .tell("You cannot unsubscribe yourself.");
    mname = .mail_name(listr);
    if (!(list in (subscribed.keys())))
        return .tell("You are not subscribed to " + mname);
    .unsubscribe(list);
    .tell(("Successfully unsubscribed from" + mname) + ".");
.

method subscribe_cmd
    arg cmd, str;
    var list, mname;
    
    (> .perms(sender(), 'this) <);
    list = $mail_utils.match_mail_recipient(str);
    mname = $mail_utils.mail_name(list);
    if (list in (subscribed.keys()))
        return .tell(("You are already subscribed to " + mname) + ".");
    if (!(list.list_is_readable_by(this())))
        return .tell(mname + " is not subscribeable by you.");
    .subscribe(list);
    .tell(("Successfully subscribed to " + mname) + ".");
.

method subscribe
    arg list;
    
    (> .perms(sender(), 'this) <);
    subscribed = subscribed.add(list, time());
.

method unsubscribe
    arg list;
    
    (> .perms(sender(), 'this) <);
    subscribed = subscribed.del(list);
.

method mail_lists_cmd
    arg cmd;
    var l, line;
    
    (> .perms(sender(), 'this) <);
    for l in (($mail_db.database()).values()) {
        line = "";
        if (l.list_is_readable_by(this()))
            line = "[Readable]";
        if (l.list_is_sendable_by(this()))
            line = ("[Sendable]" + (line ? " " | "")) + line;
        .tell((pad(l.mail_name(), ((.linelen()) - strlen(line)) - 1) + " ") + line);
    }
.

method new_list
    arg list;
    
    (> .perms(sender(), 'this) <);
    if (list in (subscribed.keys()))
        subscribed = subscribed.add(list, time());
    current = #[['location, list.start()], ['list, list]];
.

method init_mail_ui
    (> .perms(caller(), $root) <);
    subscribed = #[[this(), time()]];
    .new_list(this());
.

method mail_on_cmd
    arg cmd, rng, on, list;
    var syn, r, all_mail, mail, x, line;
    
    (> .perms(sender(), 'this) <);
    syn = cmd + " [<range> on <mail list>]";
    catch any {
        list = $mail_utils.match_mail_recipient(list);
        if (list != (current['list]))
            .new_list(list);
        all_mail = (current['list]).mail();
        if (!all_mail) {
            .tell(("No mail on " + ($mail_utils.mail_name(list))) + ".");
            return;
        }
        if (!rng) {
            r = [1, listlen(all_mail)];
            rng = r;
        } else {
            rng = $parse.range(rng);
            r = $mail_utils.range_to_actual(rng, current);
        }
    } with handler {
        switch (error()) {
            case ~listnf, ~range:
                .tell((traceback()[1])[2]);
            default:
                rethrow(error());
        }
        return;
    }
    line = "Mail";
    if ((r[1]) != (r[2]))
        line = (((line + " from ") + tostr(rng[1])) + " to ") + tostr(rng[2]);
    line = ((line + " on ") + ($mail_utils.mail_name(current['list]))) + ":";
    .tell(line);
    for x in [r[1] .. r[2]] {
        mail = all_mail[x];
        line = (mail == (current['location])) ? "=>" | "  ";
        line = (line + pad(tostr(x), -3)) + ":";
        line = (line + ((mail.has_read(this())) ? " " | "!")) + " ";
        line = (line + pad(mail.subject(), (.linelen()) - 38)) + " ";
        line = (line + pad((mail.from()).name(), 19)) + " ";
        line = line + pad($time.ldate(mail.time(), 'date), 9);
        .tell(line);
    }
    .tell("------");
.