import java.net.*;
import java.io.*;
import java.util.*;

class ChatServer extends Thread {
  final static int PORT = 12345;
  static Vector outStreams = new Vector();

  PrintStream out;
  String name;
  Socket sock;

  public ChatServer(Socket sock) {
    this.sock = sock;
    start();
  }
        
  public void run() {
    BufferedReader in;
    String line;  
    try {
      in = new BufferedReader(
      new InputStreamReader(sock.getInputStream()));
      out = new PrintStream(sock.getOutputStream()); 
      name = in.readLine();         // liest Namen des neuen Chatters
      synchronized (outStreams) {
        for (int i = 0; i < outStreams.size(); i++) {
          ((PrintStream)outStreams.get(i)).println(name + " joins");
        }                           // Meldung an alle: Neuer Chatter
        outStreams.add(out);        // OutputStream hinzufügen
      }
      while (true) {                // Hauptschleife:
        line = in.readLine();       // vom Clienten lesen
	    if (line == null) break;    // bis EOF 
	    synchronized (outStreams) { // an alle Clienten ausgeben
          for (int i = 0; i < outStreams.size(); i++) {
            ((PrintStream)outStreams.get(i)).println(name + ": " + line);
          }
        }
      }
      synchronized (outStreams) {
        outStreams.remove(out);     // entfernt den Chatter
        sock.close();               // schließt den Socket
        for (int i = 0; i < outStreams.size(); i++) {
          ((PrintStream)outStreams.get(i)).println(name + " leaves");
        }                           // Meldung an alle: Chatter ist weg
      }
    } catch(IOException e) {e.printStackTrace();}
  }

  public static void main(String[] args) {
    ServerSocket listenSocket;
    try {
      listenSocket = new ServerSocket(PORT);
      while (true) {
        Socket sock = listenSocket.accept();
        new ChatServer(sock);
      }
    } catch(IOException e) {e.printStackTrace();}
  }
}