/
CDC-1.2b/
CDC-1.2b/src/
parent $db
object $registry

var $root dbref 'registry
var $root child_index 0
var $root fertile 0
var $root manager $registry
var $root owned [$registry]
var $root owners [$core]
var $root writable []
var $root readable ['parameters, 'methods, 'code]
var $db database #[]
var $root inited 1
var $registry stripped_characters ""
var $registry min_char_len 0
var $registry max_char_len 0
var $registry max_word_len 0
var $registry reserved_names []
var $registry invalid_names []

method init_registry
    .perms(caller(), $root);
    .set_trusted(1);
.

method uninit_registry
    .perms(caller(), $root);
    reserved_names = 0;
    invalid_names = 0;
    trusted = 0;
    stripped_characters = 0;
.

method set_max_word_len
    arg value;
    
    .perms(sender(), 'manager);
    if (type(value) != 'integer)
        throw(~type, "Value is not an integer");
    max_word_len = value;
.

method set_max_char_len
    arg value;
    
    .perms(sender(), 'manager);
    if (type(value) != 'integer)
        throw(~type, "Value is not an integer");
    max_char_len = value;
.

method set_min_char_len
    arg value;
    
    .perms(sender(), 'manager);
    if (type(value) != 'integer)
        throw(~type, "Value is not an integer");
    min_char_len = value;
.

method set_stripped_characters
    arg string;
    
    .perms(sender(), 'manager);
    if (type(string) != 'string)
        throw(~type, "Value is not a string.");
    stripped_characters = string;
.

method insert
    arg name, obj;
    
    // registers obj with obj.name
    //  .perms(caller(), 'trusts);
    if (stripped_characters)
        name = $string.strip(name, stripped_characters);
    (> pass(name, obj) <);
.

method remove
    arg name;
    
    // removes the object from the database. 
    // THIS: is what is broken with guests, should fix it.
    // .perms(caller(), 'trusts);
    if (stripped_characters)
        name = $string.strip(name, stripped_characters);
    (> pass(name) <);
.

method database
    if (!('parameters in (.is_readable_by(sender()))))
        throw(~perm, "Database is not readable by sender.");
    return (> pass() <);
.

method exact_match
    arg name;
    
    // returns a direct match of the name (if there is one)
    if (!('parameters in (.is_readable_by(sender()))))
        throw(~perm, "Database is not readable by sender.");
    if (stripped_characters)
        name = $string.strip(name, stripped_characters);
    return (> pass(name) <);
.

method valid_name
    arg name;
    var word, sname;
    
    // returns 1 if the name is valid
    /// if (!('parameters in .is_readable_by(sender())))
    //    throw(~perm, "Database is not readable by sender.");
    (> .perms(caller(), 'trusts) <);
    
    // check name itself first
    sname = name;
    if (stripped_characters)
        sname = $string.strip(name, stripped_characters);
    if (max_word_len && (listlen(explode(name)) > max_word_len))
        throw(~invname, ("Names can only be " + tostr(max_word_len)) + " words long.");
    if (min_char_len && (strlen(sname) < min_char_len))
        throw(~invname, ("Names must have at least " + tostr(min_char_len)) + " alpha-numeric characters in them");
    if (max_char_len && (strlen(name) > max_char_len))
        throw(~invname, ("Names can only be " + tostr(max_char_len)) + " characters long.");
    
    // see if it already exists
    if ((| .exact_match(name) |)) {
        if (!(((.database())[sname]) == sender()))
            throw(~invname, "Name already exists.");
    }
    
    // check reserved and invalid names
    for word in (explode(name)) {
        if (reserved_names && (word in reserved_names))
            throw(~invname, ("`" + word) + "' is a reserved name.");
        if (invalid_names) {
            for word in (invalid_names) {
                if (match_pattern(("*" + word) + "*", name))
                    throw(~invname, ("`" + word) + "' is not allowed as part of a name.");
            }
        }
    }
.

method match_begin
    arg name;
    var matches, obj;
    
    // returns a direct match, or partial matches
    if (stripped_characters)
        name = $string.strip(name, stripped_characters);
    return (> pass(name) <);
.

method stripped_characters
    return stripped_characters;
.

method key_changed
    arg old_name, new_name;
    
    // adjusts the database for the new name
    .perms(caller(), 'trusts);
    if (stripped_characters) {
        old_name = $string.strip(old_name, stripped_characters);
        new_name = $string.strip(new_name, stripped_characters);
    }
    (> pass(old_name, new_name) <);
.

method find
    arg name;
    var tmp;
    
    if (.stripped_characters())
        name = $string.strip(name, .stripped_characters());
    if (!name)
        throw(~namenf, "No matches found.");
    tmp = (| .exact_match(name) |);
    if (tmp)
        return tmp;
    catch any {
        tmp = (> .match_begin(name) <);
    } with handler {
        switch (error()) {
            case ~ambig:
                rethrow(error());
            default:
                throw(~namenf, "No matches found.");
        }
    }
    return tmp;
.