
// The NetworkCodedMessage class defines two static methods that can
// be used to send and receive coded messages over the Internet.

import java.io.*;  // Make Java input/output classes available.
import java.net.*; // Make Java networking classes available.

class NetworkCodedMessage {

  static int PORT = 4242;  // Network port used for sending messages.
                           // (Internet communication requires a host
                           // address and a port number.  The user must
                           // specify the host address.)

  static void send(Console console) {
         // Get a one-line message from the user, code it using a key
         // word specified by the user, and send it to an Internet
         // host specified by the user.  The console which is passed
         // as a parameter is used for communication with the user.

      console.putln("To use this feature, you must specify a one-line message,");
      console.putln("a key word to be used for coding it, and an Internet");
      console.putln("address to which the message will be sent.  Before you");
      console.putln("procede, make sure you know the address of the recipient");
      console.putln("and that the recipient knows the key word.");
      console.putln("");
      console.put("Do you want to continue? ");
      boolean OK = console.getlnBoolean();
      if (!OK) {
         console.putln("OK.  Returning to main menu.");
         return;
      }

      console.put("Enter your message: ");  // get user's message
      String message = console.getln();

      console.put("Enter the key word: ");  // get keyword and make Coder object
      String key = console.getln();
      Coder coder = new Coder(key);

      console.put("Enter the Internet address to send to: ");  // get recipient address
      String host = console.getln();

      try {  // Open a connection, get a output steam, and send the coded message.
         Socket socket = new Socket(host,PORT);
         PrintStream out = new PrintStream(socket.getOutputStream());
         out.println(coder.encode(message));
         console.close();
         console.putln("Done.");
      }
      catch (IOException e) {
         console.putln("Sorry, an error occurred:");
         console.putln(e.toString());
      }

   }  // end of sendNet()


   static void receive(Console console) {
         // This routine will listen for an incoming connection, read a
         // coded message message from it, and decode it using a key
         // word specified by the user.  The console that is passed as
         // a parameter is used for communication with the user.

      console.putln("If you procede, the program will print out the Internet");
      console.putln("address of the computer you are using.  It will then wait");
      console.putln("for a connection from someone trying to send a coded message");
      console.putln("to that address.  Make sure that there is someone who wants");
      console.putln("to send you a message and that you know the key word that");
      console.putln("they will use to encode the message.");
      console.putln();
      console.put("Do you want to continue? ");
      boolean OK = console.getlnBoolean();
      if (!OK) {
         console.putln("OK.  Returning to main menu.");
         return;
      }

      try {  // Get address of this compute and display it.
         InetAddress me = InetAddress.getLocalHost();
         byte[] p = me.getAddress();
         int[] ip = new int[4];
         for (int i = 0; i < 4; i++) {
            ip[i] = p[i];
            if (ip[i] < 0)
               ip[i] = 256 + ip[i];
         }
         console.putln("Listening for a message at address:  "
                               + ip[0] + "." + ip[1] + "." + ip[2] + "." + ip[3]);
      }
      catch (UnknownHostException e) {
         console.putln("Sorry, don't seem to be able to use the Net.");
         return;
      }

      String codedMessage;
      
      try {  // Listen for a connection and then read a coded message from it.
         ServerSocket listener = new ServerSocket(PORT);
         Socket socket = listener.accept();
         listener.close();  // listener is no longer needed
         DataInputStream in = new DataInputStream(socket.getInputStream());
         codedMessage = in.readLine();
         in.close();
      }
      catch (IOException e) {
         console.putln("Sorry, an error occurred.");
         console.putln(e.toString());
         return;
      }

      console.putln();    // Display the received coded message.
      console.putln("Received coded message:");
      console.putln("  " + codedMessage);
      console.putln();
      console.put("Enter key to decode: ");  // Get key word from user and decode message.
      String key = console.getln();
      Coder coder = new Coder(key);
      console.putln();
      console.putln("Decoded message:");
      console.putln("  " + coder.decode(codedMessage));

   }  // end of receiveNet()



}