/
ColdCore-3.0a9.02/
ColdCore-3.0a9.02/src/
new object $mail_list: $mail_root, $has_name;

var $has_name name = ['uniq, "mail_list", "the mail_list"];
var $mail_list last_received_on = 0;
var $mail_list mail = [];
var $mail_list notify = [$mail_list];
var $mail_list readers = 1;
var $mail_list senders = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root inited = 1;
var $root managed = [$mail_list];
var $root manager = $mail_list;
var $root trusted_by = [$mail_db];

protected method ._announce_new_mail() {
    arg new_mail;
    var line, who, n;
    
    if (!notify)
        return;
    line = ((((.mail_name()) + " has been sent new mail by ") + ((new_mail.from()).name())) + ": ") + (new_mail.subject());
    for who in (notify)
        (| who.tell(line.chop(who.linelen())) |);
};

public method .add_mail() {
    var new_mail;
    
    (> .perms(caller(), $mail_message) <);
    last_received_on = time();
    new_mail = sender();
    
    // make sure we do not already have it
    if (new_mail in mail)
        return;
    
    // add it
    mail = mail.add(new_mail);
    ._announce_new_mail(new_mail);
};

public method .add_sender_to_notification() {
    var who;
    
    who = sender();
    if (!(who.has_ancestor($user)))
        throw(~type, "Sender is not a user.");
    if (!(.has_flag('sender, who)))
        throw(~perm, ((who.name()) + " cannot read ") + (.mail_name()));
    notify = setadd(notify, who);
};

root method .core_mail_list() {
    var o;
    
    if (type(senders) == 'list)
        senders = filter o in (senders) where (valid(o));
    if (type(notify) == 'list)
        notify = filter o in (notify) where (valid(o));
    if (type(readers) == 'list)
        readers = filter o in (readers) where (valid(o));
};

public method .del_mail() {
    arg old_mail, @sender;
    
    // what the hell am I thinking?
    [(sender ?= sender())] = sender;
    if (!($mail_lib.has_mail_perms(caller())))
        throw(~perm, ((caller().namef('xref)) + " cannot remove ") + (old_mail.mail_name()));
    if (old_mail == (mail.last()))
        last_received_on = (| (mail[(mail.length()) - 1]).time() |) || 0;
    (| old_mail.del_recipient(this()) |);
    mail = mail.del(old_mail);
};

public method .del_sender_from_notification() {
    var who;
    
    who = sender();
    if (!(who.has_ancestor($user)))
        throw(~type, "Sender is not a user.");
    if (!(.has_flag('sender, who)))
        throw(~perm, ((who.name()) + " cannot read ") + (.mail_name()));
    notify = notify.setremove(who);
};

root method .init_mail_list() {
    mail = [];
    senders = 1;
    readers = [.manager()];
    notify = [.manager()];
    if (!(.has_ancestor($user))) {
        readers = 1;
        (| $mail_db.insert(.name(), this()) |);
    } else {
        readers = [.manager()];
    }
};

public method .last_received_on() {
    return last_received_on;
};

public method .list_is_readable_by() {
    arg who;
    
    if (.is_writable_by(who))
        return 1;
    if (type(readers) == 'list)
        return who in readers;
    return readers;
};

public method .list_is_sendable_by() {
    arg who;
    
    if (.is_writable_by(who))
        return 1;
    if (type(senders) == 'list)
        return who in senders;
    return senders;
};

public method .mail() {
    //  if (!.list_is_sendable_by(sender()))
    //      throw(~perm, "Sender cannot read " + .mail_name() + ".");
    return mail;
};

public method .mail_list_next() {
    arg cur;
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, "Sender cannot read this list.");
    return (> mail[(cur in mail) + 1] <);
};

public method .mail_list_prev() {
    arg cur;
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, "Sender cannot read this list.");
    return (> mail[(cur in mail) - 1] <);
};

public method .mail_name() {
    return $mail_lib.mail_name(this());
};

public method .notify() {
    (> .perms(sender(), 'manager) <);
    return notify;
};

public method .notify_bad_mail() {
    arg badmail;
    
    // this is a hack, we shouldn't ever get bad mail if things worked right
    (> .perms(caller(), $mail_ui) <);
    mail = setremove(mail, badmail);
};

public method .recent_mail() {
    arg @diff;
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, ("Sender cannot read " + (.mail_name())) + ".");
    [(diff ?= 20)] = diff;
    if ((mail.length()) < diff)
        return [0, mail];
    return [((mail.length()) - diff) - 1, mail.subrange((mail.length()) - diff)];
};

public method .senders() {
    (> .perms(sender(), 'manager) <);
    return senders;
};

public method .set_name() {
    arg new_name, @args;
    var old_name;
    
    old_name = .name();
    if (new_name && ((new_name[1]) == "*"))
        new_name = new_name.subrange(2);
    (> pass(new_name, @args) <);
    (| $mail_db.key_changed(old_name, new_name) |);
};

public method .set_notify() {
    arg new_value;
    
    (> .perms(sender(), 'manager) <);
    if ((type(new_value) != 'integer) && (type(new_value) != 'list))
        throw(~type, "new value must be submitted as a list of users or boolean integer.");
    notify = new_value;
};

public method .set_senders() {
    arg new_value;
    
    (> .perms(sender(), 'manager) <);
    if ((type(new_value) != 'integer) && (type(new_value) != 'list))
        throw(~type, "new value must be submitted as a list of users or boolean integer.");
    senders = new_value;
};

public method .start() {
    if (!(.list_is_readable_by(sender())))
        throw(~perm, ("Sender cannot read " + (.mail_name())) + ".");
    if (mail)
        return mail[1];
    return 0;
};

root method .uninit_mail_list() {
    var m;
    
    for m in (mail)
        .del_mail(let[1]);
    mail = [];
    senders = 1;
    readers = [.manager()];
    notify = [];
    if (!(.has_ancestor($user)))
        (| $mail_db.remove(.name()) |);
    $smtp.remove_aliases();
};