package com.roguewave.jchat;
import java.util.*;
/**
 * The ForumDispatcher class.
 *
 * <P>
 * The ForumDispatcher class implements a specialized Dispatcher for the JChat
 * server.  The ForumDispatcher maintains a list of Forums that are notified when
 * a command is processed.
 * </P>
 *
 * @see     com.roguewave.jchat.Dispatcher
 * @see		com.roguewave.jchat.Forum
 *
 * @version 1.0  96 April 4
 * @author  Eldon J. Metz
 */
public class ForumDispatcher extends Dispatcher {	
  private Hashtable forums_;

  /**
   * Creates a ForumDispatcher.  Two default Forums	are created:
   * <PRE>
   *   New Users
   *   Suggestions
   * </PRE>
   *
   * @see  com.roguewave.jchat.Forum
   */
  public ForumDispatcher() {
    super();
	forums_ = new Hashtable();

	// Add the two default forums
	forums_.put("New Users", new Forum("New Users"));
	forums_.put("Suggestions", new Forum("Suggestions"));
  }

  /**
   * Add initialization functionality when adding new Connections.
   */
  public synchronized void addConnection(Connection aConnection) {
    super.addConnection(aConnection);
	sendForumNames(aConnection);
  }

  /**
   * Adds a new Forum object that should be notified when the "post" command is
   * processed.
   */
  public synchronized void addObjectToNotify( String forumName, Object aObject ) {
	// @@@ Need to check to see if the forum already exists -- Client responsibility?
	forums_.put(forumName, new Forum(forumName));
	((Forum)forums_.get(forumName)).addConnection((Connection)aObject);
  }

  /**
   * Sends the current collection of Forum names to the specified Connection.
   */
  public synchronized void sendForumNames(Connection aConnection) {
    Enumeration forumNameEnumeration = forums_.keys();
	String[] command = new String[4];
	command[0] = "add";

    while (forumNameEnumeration.hasMoreElements()) {
		command[1] = (String)forumNameEnumeration.nextElement();
		aConnection.send(command);
	  }
  }

  /**
   * Process a command request.  The following commands are understood:
   * <PRE>
   *   attach "forumname" "username" ""
   *   detach "forumname" "username" ""
   *   create "forumname" "username" ""
   *   post   "forumname" "username" "message"
   *   close  ""          "username" ""
   * </PRE>
   */
  public synchronized void processCommand ( String[] command ) {
    // @@@ Ugly ladder implementation for processing commands
    if (command[0].equals("attach")) {
      ((Forum)forums_.get(command[1])).addConnection(((Connection)connections_.get(command[2])));
    }
    else if (command[0].equals("post")) {
      try {
        ((Forum)forums_.get(command[1])).send(command);
	  } catch (ArrayIndexOutOfBoundsException e) {
	    System.out.println("ForumDispatcher: " + e);
	  }
	}
    else if (command[0].equals("close")) {
	  ((Connection)connections_.get(command[2])).close();
	}
	else if (command[0].equals("detach")) {
	  Connection aConnection = (Connection)connections_.get(command[2]);
	  ((Forum)forums_.get(command[1])).removeConnection(aConnection);
	}
	else if (command[0].equals("create")) {
	  Enumeration connectionEnumeration = connections_.elements();
	  String[] newCommand = new String[4];
	  newCommand[0] = "add";
	  newCommand[1] = command[1];
	  forums_.put(command[1], new Forum(command[1]));
	  while (connectionEnumeration.hasMoreElements()) {
	    Connection aConnection = (Connection) connectionEnumeration.nextElement();
		aConnection.send(newCommand);
	  }
	}
  }
}
