package util.net;

import java.io.*;
import java.net.*;
import util.net.Debug;


/**
 * This object handles the io between the server and one client.
 * It has a run method that listens for information and relays it to
 * the server.   It also has a method to send information back to its
 * client.
 */
public class BabySitter implements Runnable
{
    private Server myServer;
    private Thread mySpirit;
    private SocketConnection myConnection;
    private boolean myStopped;


    /** 
     * Creates a BabySitter to handle communication with a 
     * client.  Spawns a new thread to handle input from client;
     * sends objects on request.
     */
    protected BabySitter (Socket socket, Server server)
    {
        try
        {
            myServer = server;
            myConnection = new SocketConnection(socket);
            mySpirit = new Thread(this);
            mySpirit.start();
        }
        catch (Exception e)
        {
            System.err.println("Server:  socket error in BabySitter");
            myServer.removeBabySitter(this);
        }
    }


    /**
     * Sends object to the client.
     */
    protected void send (Object o)
    {
        try
        {
            Debug.println("Server:  sending '" + o + "' to " + getRepresentedClient());
            myConnection.writeObject(o);
        }
        catch (Exception e)
        {
            System.err.println("Server:  socket error in send");
            myServer.removeBabySitter(this);
        }
    }

    /** 
     * Recieves new info from clients.
     *
     * @see Server#sendToAllExcept
     */
    public void run ()
    {
        try
        {
            Debug.println("Server:  BabySitter running for " + getRepresentedClient());
            while (!myStopped)
            {
                Object o = myConnection.readObject();
                Debug.println("Server:  read '" + o + "' from " + getRepresentedClient());
                if (o == null)
                {
                    myServer.removeBabySitter(this);
                    return;
                }
                myServer.sendToAllExcept(o, this);
            }
        }
        catch (Exception e)
        {
            System.err.println("Server:  socket error in run");
            myServer.removeBabySitter(this);
        }
    }


    /**
     * Should only be called by Server.
     * User server.removeBabySittter( BabySitter ) instead.
     */
    protected void stop ()
    {
	Debug.println("Server:  closing connection from " + getRepresentedClient());
	myStopped = true;
	myConnection = null;
    }


    public String getRepresentedClient ()
    {
	return myConnection.getRemoteHostName();
    }
}
