/*****************************************************************
 This program shows how to synchronize communication between two
 programs using a combination of two waits: one for user input
 (a mouse click) and the other for input from the socket which
 forms the channel to the other program. The program runs in two
 modes, as a server or as a client; run one version with:
 
 %java Net server
 
 and the other with:
 
 %java Net client

 The server starts by sending a message to the client on a mouse
 click. The client responds, again on a mouse click, and the 
 communication proceeds until the end is detected (actually by
 sending the number 10) when both client and server exit gracefully.
*****************************************************************/

import java.io.*;
import java.net.*;
import java.awt.*;

class Net extends Frame {
  String host;
  DataInputStream is = null;
  PrintStream os = null;
  String input = null;
  String output = "1";
  String type;
  Socket client = null;
  Canvas canvas;
  
  Net(String s) {
    type = s;
    setTitle(type);
    canvas = new Canvas();
    canvas.resize(100, 100);
    add(canvas);
    pack();
    show();
  }
  
  public static void main(String[] args) {
    // pass the first command line argument to the constructor
    // as a "type"
    new Net(args[0]).init();
  }
  
  void init() {
    try {
      // find the local host's name
      host = InetAddress.getLocalHost().getHostName();
      System.out.println(host);
    }
    catch (UnknownHostException e) {}
    
    try {
      if (type.equals("server")) {
	// a server needs a ServerSocket
	ServerSocket ss = new ServerSocket(4444);
	client = ss.accept();
      }
      else if (type.equals("client")) {
	// a client just has a socket
	client = new Socket(host, 4444);
      }
      // extract the input and output streams from the sockets
      is = new DataInputStream(client.getInputStream());
      os = new PrintStream(client.getOutputStream());
      // the client should start by waiting for a server message
      if (type.equals("client")) {
	canvas.disable();
	input = is.readLine();
	System.out.println("Received: " + input);
	int next = Integer.parseInt(input);
	output = "" + ++next;
	canvas.enable();
      }
    }
    catch (IOException e) {}
  }
  
  public boolean mouseDown(Event e, int x, int y) {
    if (e.target == canvas) {
      canvas.disable();  // make sure no more clicks are allowed
                         // until the message is processed
      System.out.println("Clicked!");
      os.println(output); // send the message to the other program
      System.out.println("Sent: " + output);
      if (output.equals("quit")) {
	// if we are sending quit, we shoud exit
	System.out.println("Done 1");
	try {
	  os.close();
	  is.close();
	  client.close();
	  System.exit(0);
      }
	catch (IOException ex) {}
      }
      try {
	// wait for input from the other program
	input = is.readLine();
      }
      catch (IOException ex) {}
      System.out.println("Received: " + input);
      if (input.equals("quit")) {
	// if the other program exited, this program should too
	System.out.println("Done 2");
	try {
	  os.close();
	  is.close();
	  client.close();
	  System.exit(0);
	}
	catch (IOException ex2) {}
      }
      // process the input (it's just an integer, sent as a string)
      int next = Integer.parseInt(input);
      if (next == 10)
	output = "quit";
      else
	output = "" + ++next;
      // make sure to allow more mouse clicks now
      canvas.enable();
      return true;
    }
    else
      return false;
  }
}


