/
area/
classes/net/sourceforge/pain/logic/
classes/net/sourceforge/pain/logic/event/
classes/net/sourceforge/pain/logic/fn/util/
classes/net/sourceforge/pain/network/console/
classes/net/sourceforge/pain/plugin/
classes/net/sourceforge/pain/plugin/reset/
classes/net/sourceforge/pain/plugin/shutdown/
classes/net/sourceforge/pain/plugin/social/
classest/net/sourceforge/pain/db/data/
doc/
doc/paindb/resources/
src/net/sourceforge/pain/logic/
src/net/sourceforge/pain/logic/event/
src/net/sourceforge/pain/logic/fn/util/
src/net/sourceforge/pain/network/console/
src/net/sourceforge/pain/network/console/telnet/
src/net/sourceforge/pain/plugin/
src/net/sourceforge/pain/plugin/command/
src/net/sourceforge/pain/plugin/reset/
src/net/sourceforge/pain/plugin/shutdown/
src/net/sourceforge/pain/plugin/social/
src/net/sourceforge/pain/util/
tests/
tests/net/sourceforge/pain/db/data/
package net.sourceforge.pain.plugin.command;

import net.sourceforge.pain.plugin.*;
import net.sourceforge.pain.util.*;
import net.sourceforge.pain.*;

import java.io.*;
import java.util.*;


/**
 * Command has the same proirity during it's parsing as it was passed in config file
 * config file format:
 * command_line, className, params(tag)
 * where
 *      command line is a console command
 *      className is a class name suffix for TextCommand.COMMAND_PACKAGE
 *      params - will ve transparently pass to command handler (commandClass instance)
 *
 *  we can't cast command to className because we need a shortcut support for command (preparse all of the commands).
 * Moreover shourtcut support should support non-alphabetical priorities (s->south but not s->sit)
 * today command has priority in order of its appearence in cfg file (south should follow before sit to bind 's' shortcut with south)
 * Socials added after command mapping loaded from file-> they have a lower priority
 */
public final class CommandMapper extends Plugin {

	private CommandRegistry registry = new CommandRegistry();

	public void init() throws Exception {
		Log.debug("CommandMapper INIT");
		loadCommands();
		Log.debug("CommandMapper INIT OK");
	}

	public void deinit() {
		Log.debug("CommandMapper DEINIT");
	}

	public void unregisterCommand(String commandName) {
		Log.debug("CommandMapper: Unregistering  Command:" + commandName);
		registry.unregisterCommand(commandName);
	}

	public void registerCommand(String commandLine, String className, String tag) {
		TextCommand command = new TextCommand(commandLine, className, tag);
		registry.registerCommand(command);
		Log.debug("Dynamic command registration:" + command.name + " registered OK");
	}

	public TextCommand findCommand(String commandPrefix) {
		return registry.findCommandByPrefix(commandPrefix);
	}

	protected void loadCommands() throws Exception {
		String fileName = Core.getApplicationPath() + "/etc/command_mapping.cfg";
		BufferedReader reader = new BufferedReader(new FileReader(fileName));
		try {
			for (String line = reader.readLine(); line != null; line = reader.readLine()) {
				if (line.startsWith("#") || line.startsWith("!")) { // comment
					continue;
				}
				if (line.trim().length() == 0) {
					continue;
				}
				StringTokenizer st = new StringTokenizer(line, ",");
				String commandLine = st.nextToken();
				try {
					String className = st.nextToken(); // without package
					String tag = null;
					if (st.hasMoreTokens()) {
						tag = st.nextToken("\n").substring(1);
					}
					TextCommand command = new TextCommand(commandLine, className, tag);
					registry.registerCommand(command);
					Log.debug("Command:" + command.name + " tag:" + command.tag + " registered OK");
				} catch (Exception e) {
					Log.error("command init failed:" + commandLine + " SKIPPING this command");
				}
			}
		} finally {
			reader.close();
		}
	}

	public Collection getCommands() {
		return Collections.unmodifiableCollection(registry.exactMapping.values());
	}

	public Set getAllCommandsForClassName(String className) {
		return Collections.unmodifiableSet(registry.getAllCommandsForClassName(className));
	}
}