/**
  * %W %E% 15-212: Fundamentals of Computer Science II, Spring 1998
  *
  * Copyright (c) 1998 Carnegie Mellon University
  *
  **/

import java.net.*;
import java.io.*;

/**
  * See the project handout for a description of what this file
  * does. In this comment, you will find information on the specific
  * protocols that the three methods must follow, and exactly what
  * they must do.
  *  
  * Your networking software will use sockets, which are implemented
  * in the package java.net. For an example of how to write client socket
  * code (it's pretty darned short), see ConnectTest.java.
  *
  * Very simply, the protocol consists of an integer (the message
  * type), and a string (the message). The message is of the form
  * "type:message\n" (no quotes, and remember that println/readLine
  * deal with the \n automatically).
  *
  * The explanations in this file are roughly four times as long as
  * the code you should write.
  *
  * Remember the old adage:
  * 
  *   If a packet hits a pocket on a socket on a port,
  *   and the bus is interrupted and teh interrupt's not caught,
  *   then the socket packet pocket has an error to report.
  * 
  * Guaranteed not to change.
  *
  * @author Salvatore Domenick Desiano
  * @version 1.09, 04/20/98 
  *
  **/

public interface Network
{
  /** 
    * This method sets up the socket connection, as a server or
    * client depending on config.isServer(). If you are the client,
    * you are connecting to the maching
    * config.getOpponentMachineName() on port config.getNetworkPort().
    *
    * If you are the server, you should set up a server socket on the
    * port config.getNetworkPort() (config.getOpponentMachineName()
    * will be null in that case).
    *
    * After you establish the connection, you should set up input and
    * output streams, saving them in your class somewhere. recieve()
    * and send() will use these variables to communicate (I reccomend
    * using a PrintWriter and a BufferedReader).
    *
    * Finally, if you are the server, you should close the server
    * socket.
    *
    **/
  public void init ( Config config ) throws IOException;

  /** 
    * This method sends information over the already open socket. In
    * fact, it shouldn't have any networking code -- it should just
    * use the streams set up by init(). This function will send a
    * message over the socket in the form "msgType:toSend\n" (again,
    * remember that \n is dealt with by println automatically). For
    * instance, send("hello?",19) would send the string "19:hello\n".
    *
    **/
  public void send ( String toSend, int msgType ) throws IOException;

  /**

    * This method is slightly more complicated, and recieves messages
    * from the already open socket. Again, no network code should
    * appear here.

    * Generally, this function should recieve a string of the form
    * "type:message\n" over the socket (just like what was sent from
    * send(), and again, remember that readLine() deals with the \n
    * for you). It then splits off the message type, and returns the
    * message. So, if "19:hello?\n" came over the socket, recieve
    * should return "hello?"
    *
    *
    * Now, there's one catch. If the incoming message doesn't match
    * the msgType passed to it, recieve() should hold onto the message
    * and return null. Now, sockets can deal with a backlog, so all
    * you need to deal with is the one current message. So, if you
    * recieve a message and it doesn't match the msgType parameter,
    * hold on to it somewhere. Until recieve() is called with the
    * correct msgType, you should continue to return null. Only when
    * recieve is called with the correct msgType do you return that
    * message. Only when that message is dealt with do you look to the
    * socket again.
    *
    * Finally, this is a blocking function. recieve() should not
    * return until it gets *something* over the net. If it is holding
    * something from a previous call, this is considered having
    * recieved something, and the function should return a value. So:
    * if you have something being held, return immediately (either
    * null or a message). If you don't have anything held, return as
    * soon as you get something over the socket (either null, and what
    * came over is held, or a message).
    *
    * This explanation is significantly longer than the code you will
    * be writing.
    **/
  public String recieve ( int msgType ) throws IOException;

}
