//
// SnakeInterface.spec
//

import java.util.Vector;
import java.util.StringTokenizer;
import java.util.NoSuchElementException;
import java.net.*;
import java.io.*;

abstract public class SnakeInterface extends Thread {
    // OVERVIEW: A SnakeInterface provides a connection between
    //    a snake and the snake server.  The SnakeInterface
    //    runs in a separate thread.  It provides methods for
    //    sending commands to the server (e.g., turnLeft turns the
    //    snake's head towards the left), and for observing the state
    //    of the snake pit (e.g., getScore).
    
    public SnakeInterface (/*@non_null@*/ Socket sock) throws IOException {
	// REQUIRES: sock has already been initialized and is 
	//    connected to the server.
	// MODIFIES: sock
	// EFFECTS: Creates a new Thread to listen for data being sent by
	//    the server.  Throws an IOException if there is a problem with
	//    the socket.
    } 

    // Abstract method that will be called whenever the state of the world has changed.
    abstract public void updateState ();

    public void startGame () {
	// EFFECTS: Sends the command to inform the server that the client 
	//   is ready to play. 
    }

    public void setSnakeName (String name) {
	// EFFECTS: Sends a command to inform the server that the client's name is name.
    }
    
    public void turnLeft () {
	// EFFECTS: Sends the command to turn the snake left (relative to 
	//   its current trajectory).
    }
    
    public void turnRight () {
	// EFFECTS: Sends the command to turn the snake right (relative to
	//    its current trajectory).
    }
    
    public int getScore () {
	// EFFECTS: Returns the client's current score as an int.
    }
    
    public boolean isPlaying () {
	// EFFECTS: Returns false if the player is out of the game for any reason,
	//    otherwise returns true if the player is still alive.
    }
    
    public /*@non_null@*/ PlainDirection getDirection () {
	// EFFECTS: Returns the current trajectory of this (N, S, E or W).
    }
    
    public /*@non_null@*/ Coordinate getBoardSize () throws RuntimeException {
	// EFFECTS: Returns the size of the board as a Coordinate, where the maximum  
	//     Coordinate that can be moved to is:
	//            Coordinate (getBoardSize ().getX () - 1, getBoardSize ().getY () - 1)
    }
    
    public /*@non_null@*/ Vector getSnake () 
        //@ensures \result.elementType == \type(Coordinate) 
        //@ensures \result.containsNull == false
    {
	// EFFECTS: Returns an ordered Vector filled with Coordinates indicating 
	//    which coordinates on the board the client's snake currently occupies.
	//    The first element in the Vector is the head, and the last is the tail.
    }
    
    public int getId () throws RuntimeException 
       //@ensures \result >= 0
    {
	// EFFECTS: Returns the id number of this snake.
    } 

    public /*@non_null@*/ Vector getApples () 
 	 //@ensures \result.elementType == \type(Coordinate)
 	 //@ensures \result.containsNull == false
    {
	// EFFECTS: Returns a Vector filled with Coordinates indicating where on
	//    the board apples are located.
    }
    
    public int getNumberOfSnakes () {
	// EFFECTS: Returns the number of snakes in the snake pit (including
	//    this snake).
    }

    //@requires n >= 0
    public Vector getNthSnake (int n) {
	// REQUIRES: n < the number of snakes in the snake pit.
	//     and n != getId (), the id of this snake.
	// EFFECTS: Returns an ordered Vector that contains all the
	//    Coordinates in the snake pit that are currently occupied
	//    by snake number n.  The snakes in the snake pit are numbered
	//    sequentially starting from 1.  If the requested snake is dead, 
	//    returns an empty vector.
    }
}