import java.net.*;
import java.io.*;

public class MulticastDiscussion implements Runnable {
  final static int MAX_DATA_SIZE = 100;
  final static String QUIT_CHAIN = "QUIT";
  
  private InetAddress address;
  private int port;
  private MulticastSocket socket;

  public static void usage() {
    StringBuilder sb = new StringBuilder();
    sb.append("Usage: java MulticastDiscussion maddr port ttl iface\n")
      .append("where\n")
      .append("\t- maddr is the multicast address (ex: 226.10.19.72)\n")
      .append("\t- port is the UDP port listening for datagram (ex: 7788)\n")
      .append("\t- ttl is the Time to Live parameter (ex: 1)\n")
      .append("\t- iface is the name of the network interface to send/receive (ex: eth0)")
      .append("\n\n")
      .append("Then, type a line of text you want to send to the group and press 'return'.\n")
      .append("To quit the application, simply type 'quit' and 'return'.\n");
    System.err.println(sb.toString());
  }
  public static void main(String[] args)
    throws Exception {
       if (args.length!=4) {
	 usage();
	 return;
       }
       MulticastDiscussion discussion =
	 new MulticastDiscussion(InetAddress.getByName(args[0]),
				 Integer.parseInt(args[1]),
				 Integer.parseInt(args[2]),
				 NetworkInterface.getByName(args[3]));
       discussion.start();
  }
  
  public MulticastDiscussion(InetAddress address, int port, int ttl, 
			     NetworkInterface netif) throws IOException {
    this.address = address;
    this.port = port;
    socket = new MulticastSocket(port);
    socket.setTimeToLive(ttl);
    socket.joinGroup(new InetSocketAddress(address,port),netif);
  }

  public void start() throws IOException  {
    Thread t = new Thread(this);
    t.setDaemon(true);
    t.start();

    BufferedReader reader =
      new BufferedReader(new InputStreamReader(System.in));
    String line;
    byte[] buffer = new byte[0];
    int len;
    DatagramPacket datag = new DatagramPacket(buffer,0,address,port);

    while ((line = reader.readLine()) != null) {
      if (QUIT_CHAIN.equals(line.toUpperCase()))
	break;
      buffer = line.getBytes("8859_1");
      for (int offset=0; offset<buffer.length; offset+=MAX_DATA_SIZE) {
	len = Math.min(buffer.length-offset, MAX_DATA_SIZE);
	datag.setData(buffer, offset, len);
	socket.send(datag);
      }
    }
    socket.leaveGroup(address);
    socket.close();
  }

  public void run() {
    try {
      byte[] buffer = new byte[MAX_DATA_SIZE];
      DatagramPacket datag = new DatagramPacket(buffer,buffer.length);
      while (true) {
	datag.setLength(MAX_DATA_SIZE);
	socket.receive(datag);
	System.out.println(datag.getAddress().getCanonicalHostName() +
	  " dit:\n\t" + new String(buffer,0, datag.getLength(),"8859_1"));
      }
    } catch (Exception e){
      e.printStackTrace();
    }
  }
}

