* @param client
	 */
	private void cmd_chat(final String arg, final Client client) {
		final Player player = getPlayer(client);

		String[] args = arg.split(" ");

		// TODO don't receive proof or confirmation of a channel's creation/deletion...

		// show a list of available channels and whether you are on them
		if (arg.equalsIgnoreCase("#channels")) {
			final List<String> sendList = new LinkedList<String>();

			sendList.add("Chat Channels");
			sendList.add("--------------------------------");

			final StringBuilder sb = new StringBuilder();

			for (final ChatChannel channel : chan.getChatChannels()) {
				if( !channel.isHidden() || checkAccess(player, Constants.WIZARD) || channel.isListener(player) ) {
					sb.append(Utils.padRight(channel.getName(), 8));
					sb.append(" ");
					sb.append(Utils.padRight("[" + channel.getShortName().toUpperCase() + "]", 5));
					sb.append(" ");

					if ( channel.isListener( player ) ) sb.append(colors("Enabled", "green"));
					else                                sb.append(colors("Disabled", "red"));

					sendList.add(sb.toString());

					sb.delete(0, sb.length());
				}
			}

			sendList.add("--------------------------------");

			send(sendList, client);
		}
		else if (args.length > 1) {
			// party #<param> <channel_name>
			final String param = args[0];

			if (param.charAt(0) == '#') { // chat subcommand
				final String channelName = args[1];
				final String password = ( args.length == 3 ) ? args[2] : ""; // TODO kludgy...

				if (param.equalsIgnoreCase("#join")) {
					final Result result = chan.add(player, channelName, password);

					String message = "";

					switch(result) {
					case JOIN:        message = "Joined channel: " + channelName;                  break;
					case WRONG_PASS:  message = "Error: Failed to join. (Wrong Password)";         break;
					case RESTRICTED:  message = "Error: Failed to join. (Channel is restricted!)"; break;
					case CURR_LISTEN: message = "Error: Failed to join. (already listening).";     break;
					case NO_CHANNEL:  message = "Error: Failed to join. (No Such Channel)";        break;
					default: break;
					}
					
					send("Chat> " + message, client);
					
					// kludge
					if( result == Result.JOIN ) chan.send(channelName, player.getName() + " joined the channel.");
				}
				else if ( param.equalsIgnoreCase("#leave") ) {
					final Result result = chan.remove(player, channelName);
					
					String message = "";
					
					switch(result) {
					case LEAVE:         message = "Chat> Left channel: " + channelName;              break;
					case CURR_NOLISTEN: message = "Chat> Error: Failed to leave. (Not Listening).";  break;
					case NO_CHANNEL:    message = "Chat> Error: Failed to leave. (No Such Channel)"; break;
					default: break;
					}
					
					send(message, client);
					
					// kludge
					if( result == Result.LEAVE ) chan.send(channelName, player.getName() + " left the channel.");
				}
				else if (param.equalsIgnoreCase("#listeners")) { // argument: show listeners on a specific channel
					final List<String> sendList = new LinkedList<String>();

					if( checkAccess(player, Constants.WIZARD) ) {
						sendList.add("Listeners on Chat Channel: " + channelName.toUpperCase());
						sendList.add("------------------------------");

						for (final Player p : chan.getListeners(channelName)) {
							sendList.add(p.getName() + "\n");
						}

						sendList.add("------------------------------");

						send(sendList, client);
					}
					else send("Chat> Error: param '#listeners' requires Admin permissions.", client);
				}
				else if (param.equalsIgnoreCase("#restrict")) {
					if( checkAccess(player, Constants.ADMIN) ) {
						final int restrict = Utils.toInt(args[2], 0);
						
						final Result result = chan.modifyRestriction(channelName, restrict);
						
						switch(result) {
						case MODIFY_OK:
							send("Chat> " + channelName + " restriction changed to " + restrict, client);
							break;
						case MODIFY_NOK:
							send("Chat>  " + channelName + " invalid restriction.", client);
							break;
						case NO_CHANNEL:
							send("No such channel.", client);
							break;
						default:
							break;
						}
					}
					else send("Chat> Error: param '#restrict' requires Admin permissions.", client); 
				}
				else if (param.equalsIgnoreCase("#destroy")) {
					// test for permissions
					if( checkAccess(player, Constants.ADMIN) ) {
						chan.destroyChannel(channelName);
						send("Chat> Destroyed channel: " + channelName + ".", client);
					}
					else send("Chat> Error: param '#destroy' requires Admin permissions.", client);
				}
				else if (param.equalsIgnoreCase("#create")) {
					// test for permissions
					if( checkAccess(player, Constants.ADMIN) ) {
						chan.makeChannel(channelName);
						send("Chat> Created new channel: " + channelName + ".", client);
					}
					else send("Chat> Error: param '#create' requires Admin permissions.", client);
				}
				/*else {
					send("No such chat channel.", client);
				}*/
			}
		}
		else { // sending a chat message
			final String test = chan.resolveShortName(args[0]);

			final String channelName = test.equals("") ? args[0] : test;
			final String msg = arg.replace(channelName, "").trim();

			if (chan.hasChannel(channelName)) {
				chan.send(channelName, player, msg);

				debug("New message (" + channelName + "): " + msg);

				logChat("(" + channelName + ") <" + player.getName() + "> " + arg);
			}
			else {
				send("Chat> No such chat channel.", client);
			}
		}
	}