package breakout;
import java.io.*;
import java.net.*;
import gamefinder.*;

/**
 *
 * A class which has methods to read and write. Works with BOServer.java and ClientHandler.java.
 * Uses Gamefinder, created by Mike Wessler, to get the hostname and port.
 *
 * @author  Jennifer Shieh 
 * @see		java.lang.Runnable
 * @see		breakout.BOServer
 * @see		breakout.ClientHandler
 *
 */
 
public class BOClient
{
	/**
	 * The Socket on which the Server listens, the network connection
	 */
	private Socket s;				
	/**
	 * Where to get information from the Server
	 */	
	private DataInputStream dis;	
	/**
	 * Where to send information to the ClientHandler
	 */	
	private DataOutputStream dos;
	
	
	/**
	 * 	Creates a client which is connected to the BOServer.  Takes no arguments.  It creates a new Socket connected to
	 *	the port returned by gl.getPort() on the host with name gl.getAddress(), features of Mike Wessler's GameFinder.
	 *	Makes new DataOutputStream and DataInputStream, which are given the OutputStream and InputStream of the Socket
	 * 	described above.
	 */
	public BOClient() 
	{
		//		GameLocation gl = GameFinder.findGame();
		try
		{	
			this.s = new Socket("oliver.mit.edu", 6667);
			this.dos = new DataOutputStream( this.s.getOutputStream() );
			this.dis = new DataInputStream( this.s.getInputStream() );
		}
		catch(IOException ioe)
		{
			System.out.println("I caught an IOException in BOClient constructor");
		}	
	}
	
	/**
	 *	Reads one int from the Server.  Returns that int.  Generally, either the x or the y coordinate of the ball
	 *
	 *	@return i the int read from the DataInputStream connected to the Server
	 *
	 *	@see java.io.DataInputStream#readInt()
	 */		
	public int read()
	{	
		int i = 0;
		try
		
		{
			/*
			 *i is assigned the value of an int read from the Server
			 */
			i = this.dis.readInt();
		}
		catch(IOException ioe)
		{
			System.out.println("I caught an IOException BOClient read");
		}		
		return i;
	}
	
	/**
	 *	Reads one int from the Server.  Returns that int, which represents the current number of players
	 *
	 *	@return i the player ID, or number of players, read from the DataInputStream connected to the Server
	 *
	 *	@see java.io.DataInputStream#readInt()
	 */			
	public int readTag()
	{
		int i = 0;
		try
		{
			i = this.dis.readInt();
		}
		catch(IOException ioe)
		{
			System.out.println("IOException BOClient readTag");
		}
		return i;	
	}
	
	/**
	 *	Returns the number of bytes that can be read from the input stream connected to the Server without blocking
	 *
	 *	@see java.io.FilterInputStream#available()
	 */
	public int available()
	{
		try 
		{
			return this.dis.available();
		}
		catch (IOException ioe)
		{
			return 0;
		}
	}

	/**
	 *	Sends the specified int to the ClientHandler connected by the DataOutputStream.  Flushes after every write.
	 *
	 *	@param int i  the int which should be sent
	 *
	 *	@see java.io.DataOutputStream#writeInt(int)
	 *	@see java.io.DataOutputStream#flush()
	 *
	 */	
	public void send(int i)
	{
		try
		{
			this.dos.writeInt(i);
			this.dos.flush();
		}
		catch(IOException ioe)
		{
			System.out.println("I caught an IOException: Client send(int)");
		}
	}
	
	/**
	 *	Sends two ints, x and y coordinates, to the ClientHandler connected by the DataOutputStream.  Flushes after every write.
	 *
	 *	@param int x  the x coordinate to be sent
	 *	@param int y  the y coordinate to be sent	 
	 *
	 *	@see java.io.DataOutputStream#writeInt(int)
	 *	@see java.io.DataOutputStream#flush()
	 *
	 */				
	public void sendCoords(int x, int y)
	{	
		try
		{
			this.dos.writeInt(x);
			this.dos.writeInt(y);
			this.dos.flush();
		}
		catch(IOException ioe)
		{
			System.out.println("I caught an IOException in BOClient sendCoords");
		}		
	}

	/**
	 *	A method used to flush() the DataOutputStream.
	 *
	 *	@see java.io.DataOutputStream#flush()
	 */
	public void cleanUp()
	{
		try
		{
			this.dos.flush();	
		}
		catch(IOException ioe)
		{
		}
	}
}
