import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.InetAddress;
import java.io.IOException;
import java.io.OutputStream;
import java.util.EventObject;
import java.util.Vector;

public class MooSrv implements SocketListener
{
  private JTextArea srvConns;

  public MooSrv(JFrame mooFra) {
    srvConns = new JTextArea(10,32);
    srvConns.setEditable(false);

    mooFra.getContentPane().setLayout(new BorderLayout());
    mooFra.getContentPane().add(BorderLayout.NORTH, new JLabel("Connections"));
    mooFra.getContentPane().add(BorderLayout.CENTER, new JScrollPane(srvConns));

    mooFra.pack();
    mooFra.setVisible(true);

    MooSrvThread serveryThing = new MooSrvThread();
    serveryThing.addSocketListener(this);
    serveryThing.start();
  }

  public void socketEvent(SocketEvent e)
  {
    srvConns.append(e.getSocket().getInetAddress().getHostAddress() + "\n");
  }

  public static void main(String args[]) {
    JFrame f = new JFrame("Moo-Serv");

    f.addWindowListener(new MooSrvAdapter());

    MooSrv srvPan = new MooSrv(f);
  }
}

class MooSrvAdapter extends WindowAdapter {
   public void windowClosing(WindowEvent e)
   {
      // close files, etc.
      System.exit(0); 
   }
}

class MooSrvThread extends Thread {
  private Vector myListeners;

  public MooSrvThread() { myListeners = new Vector(); }

  // Check already there?
  public void addSocketListener(SocketListener l)
    { myListeners.addElement(l); }
  // Check there?
  public void removeSocketListener(SocketListener l)
    { myListeners.removeElement(l); }

  protected void fireSocketEvent(SocketEvent e)
  {
    SocketListener l;

    for (int i=0; i<myListeners.size(); i++)
    {
      l = (SocketListener)myListeners.elementAt(i);
      l.socketEvent(e);
    }
  }

  public void run() {
    Socket clientSock;
    ServerSocket srvSock;
    MooCliThread cliThread;

    try {
      srvSock = new ServerSocket(1234,5);

      for(;;) {
        clientSock = srvSock.accept();

        fireSocketEvent(new SocketEvent(this, clientSock));

        cliThread = new MooCliThread(clientSock);
        cliThread.start();
      }
    } catch (Exception e) {
      System.out.println("The server thread died");
      // Hmm. If there's no server there's nothing to do.
      System.exit(-1);
    }
  }
}

class MooCliThread extends Thread {
  private Socket mySock;

  MooCliThread(Socket newSock) { mySock = newSock; }

  public void run() {
    OutputStream oStr;
    String msg = "moo!\r\n";

    try {
      oStr = mySock.getOutputStream();
      oStr.write(msg.getBytes());
      oStr.flush();
      oStr.close();

      mySock.close();
    } catch (Exception e) {
      // something didn't work.  aww.
      System.out.println("A client thread died");
    }
  }

  public String myIpAddr() {
    return mySock.getInetAddress().getHostAddress();
  }
}

interface SocketListener
{
  public void socketEvent(SocketEvent e);
}

class SocketEvent extends EventObject
{
  private Socket evSock;

  public SocketEvent(Object source, Socket newSock)
  {
    super(source);

    evSock = newSock;
  }

  public String getMessage() { return "client connected"; }
  public Socket getSocket() { return evSock; }
}
