/
codebase/src/net/sourceforge/pain/admin/console/command/
codebase/src/net/sourceforge/pain/data/role/
codebase/src/net/sourceforge/pain/network/console/telnet/
codebase/src/net/sourceforge/pain/network/guitool/
codebase/src/net/sourceforge/pain/plugin/
codebase/src/net/sourceforge/pain/util/
db/src/net/sourceforge/pain/util/
gui/
gui/lib/
gui/src/net/sourceforge/pain/tools/guitool/dbbrowse/
gui/src/net/sourceforge/pain/tools/guitool/dialog/
gui/src/net/sourceforge/pain/tools/guitool/menu/
gui/src/net/sourceforge/pain/tools/guitool/resources/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/explorer/
mudlibs/tinylib/
mudlibs/tinylib/area/
mudlibs/tinylib/etc/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/affect/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/prototype/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/trigger/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/affect/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/deploy/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/guitool/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/guitool/event/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/fn/util/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/trigger/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/trigger/impl/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/command/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/reset/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/shutdown/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/social/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/util/
tests/
tests/src/
tests/src/net/sourceforge/pain/db/data/
package net.sourceforge.pain.tinylib.plugin.command;


import net.sourceforge.pain.util.*;

import java.util.*;

public class CommandRegistry {

    private final HashMap prefixMapping = new HashMap(1024);
    final HashMap exactMapping = new HashMap(1024);
    private final HashMap commandNamesByClassName = new HashMap(1024);

    CommandRegistry() {
    }

    public LinkedHashMap findCommandsByPrefix(String prefix) {
        prefix = prefix.toLowerCase();
        PrefixEntry entry = (PrefixEntry) prefixMapping.get(prefix);
        if (entry == null) {
            return null;
        }
        return entry.commands;
    }

    public void registerCommand(TextCommand command) {
        final String name = command.name;
        if (exactMapping.containsKey(name)) {
            throw new IllegalArgumentException("command with this name already registered:" + name);
        }
        for (int i = 0; i < name.length(); i++) {
            String prefix = name.substring(0, i + 1);
            PrefixEntry entry = (PrefixEntry) prefixMapping.get(prefix);
            if (entry == null) {
                entry = new PrefixEntry();
                prefixMapping.put(prefix, entry);
            }
            entry.commands.put(name, command);
        }
        exactMapping.put(name, command);
        addToClassNameMapping(command);
    }

    private void addToClassNameMapping(TextCommand command) {
        HashSet commandNames = (HashSet) commandNamesByClassName.get(command.commandClassName);
        if (commandNames == null) {
            commandNames = new HashSet();
            commandNamesByClassName.put(command.commandClassName, commandNames);
        }
        commandNames.add(command.name);
    }

    public void unregisterCommand(String name) {
        name = name.toLowerCase();
        TextCommand command = (TextCommand) exactMapping.remove(name);
        if (command == null) {
            return;
        }
        for (int i = name.length(); i > 0; i--) {
            String prefix = name.substring(0, i);
            PrefixEntry entry = (PrefixEntry) prefixMapping.get(prefix);
            if (entry == null) {
                return;
            }
            entry.commands.remove(name);
            if (entry.commands.isEmpty()) {
                prefixMapping.remove(prefix);
            }
        }
        removeFromClassNameMapping(command);
    }

    private void removeFromClassNameMapping(TextCommand command) {
        HashSet commandNames = (HashSet) commandNamesByClassName.get(command.commandClassName);
        if (commandNames == null) {
            Log.warn("BUG:removeFromClassNameMapping: commandsNames is null");
            return;
        }
        commandNames.remove(command.name);
        if (commandNames.isEmpty()) {
            commandNamesByClassName.remove(command.commandClassName);
        }
    }


    public TextCommand findCommandByPrefix(String prefix) {
        LinkedHashMap commandsByPrefix = findCommandsByPrefix(prefix);
        if (commandsByPrefix == null || commandsByPrefix.isEmpty()) {
            return null;
        }
        return (TextCommand) commandsByPrefix.values().iterator().next();
    }

    public Set getAllCommandsForClassName(String className) {
        return (Set) commandNamesByClassName.get(className);
    }

    private static class PrefixEntry {
        LinkedHashMap commands = new LinkedHashMap();
    }

}