import objectdraw.*;
import javax.swing.*;
import java.awt.event.*;

// This class manages the network communication for the user who is making
// guesses.
public class Guesser extends ActiveObject implements ActionListener {
   // Location and size of winning message
   private static final int WINNING_MSG_OFFSET = 50;
   private static final int WINNING_MSG_SIZE = 18;

   // The stream on which the Lines are received as the drawer draws them.
   private ObjectInputStream in;
   // The stream on which guesses are sent as the guesser enters them.
   private PrintWriter out;
   // The canvas where the new Lines should appear.
   private DrawingCanvas canvas;
   // The field where the guesser types the guesses
   private JTextField guessField;
   // The socket used for communicating with the server.
   private Socket clientSocket;

   // Create a new guesser and establish communication with the drawer.
   // Parameters:
   //      pictionaryPort - the port on the server to connect to
   //       theCanvas - the canvas to draw Lines on
   //       theGuessField - the UI component where the user types guesses
   public Guesser (int pictionaryPort, DrawingCanvas theCanvas, 
                   JTextField theGuessField) {
      canvas = theCanvas;
      guessField = theGuessField;
      guessField.addActionListener (this);
      try {
         // Establish communication with the server.  For now,
         // these are assumed to run on the same machine.
         clientSocket = new Socket ("localhost", pictionaryPort);
         // Initialize the stream to receive Lines on
         InputStream clientInStream = clientSocket.getInputStream();
         in = new ObjectInputStream (clientInStream);
         // Initialize the stream to send guesses on.
         out = new PrintWriter (new OutputStreamWriter (clientSocket.getOutputStream()));
      } catch (UnknownHostException e) {
         System.out.println ("Unknown host.");
      } catch (IOException e) {
         System.out.println ("Could not create client.");

   // Receive Lines until the Line stream closes.
   public void run ()  {   
      // Next line received on the stream.
      Line nextLine;
      try {
         while (true) {
            // Get a line from the stream and put it on the canvas.
            nextLine = (Line) in.readObject();
            nextLine.addToCanvas (canvas);
      } catch (IOException e) {
         // Assume the connection is closed because the guesser was right, not because 
         // of a network problem.  Display a congratulatory message.      
         Text rightText = new Text ("You're right!!", WINNING_MSG_OFFSET, 
                                                    WINNING_MSG_OFFSET, canvas);
         rightText.setFontSize (WINNING_MSG_SIZE);
      } catch (Exception e) {
         System.out.println (e);

   // React to carriage returns in the guess field by sending the guesses
   // to the drawer.  Extra carriage return and flush needed for some reason.
   public void actionPerformed (ActionEvent evt) {
      out.println (guessField.getText());

   // Clean up all the open streams   
   private void close () {
      if (out != null) {
      try {
         if (in != null) {
      } catch (IOException e) { 
            // ignore it if can't close in
      try {
         if (clientSocket != null) {
      } catch (IOException e){
           // ignore it if can't close clientSocket