//   Course Number: COSC 650 Data Comm/Networks
//      Class Name: ClientConnection.java
//  Project Number: 2
//         Authors: Brian Hoffman
//                  Mike McKinney
//                  Javier Carrasco
//     Description: This class encapsulates all of the information that the
//                  client needs to know about its connection to the server.
//                  It keeps track of the socket, the input and output streams,
//                  and the nickname the participant gave to identify themselves
//                  for the duration of the connection. 

// Java Core Packages
import java.io.*;
import java.net.*;

public class ClientConnection
{ 
    private Socket connection;
    private String serverAddress;
    private int portNum;
    private String userName;
    private ObjectOutputStream output;
    private ObjectInputStream input;
    
    /**
     * ------------------------------------------------------------------------
     * constructor 
     * ------------------------------------------------------------------------
     */
    public ClientConnection(String server, int pNumber, String name)
    {
        serverAddress = server;
        portNum = pNumber;
        userName = name;
    }
    
    /**
     * ------------------------------------------------------------------------
     * connect - establishes a connection and sets up IO streams
     * ------------------------------------------------------------------------
     */ 
    public boolean connect()
    {
        try
        {
            connection = new Socket(InetAddress.getByName(serverAddress), portNum);
            connection.setSoTimeout(500);
            
            // get the input and output streams and flush header from output
            output = new ObjectOutputStream(connection.getOutputStream());
            output.flush();
            input = new ObjectInputStream(connection.getInputStream());
                
            return true;
        }        
        catch(IOException ioException)
        {
            ioException.printStackTrace();
            return false;
        }
    }
    
    /* ------------------------------------------------------------------------
     * getMethods
     *-------------------------------------------------------------------------
     */
     public String getUserName() { return userName; }
    public String getServerAddress() {return serverAddress; }
    public int getPortNum() {return portNum; }
    public Socket getSocket() { return connection; }
    public ObjectOutputStream getObjOutput() { return output; } 
    public ObjectInputStream getObjInput() { return input; }
    
    /**
     * ------------------------------------------------------------------------
     * sendMessage - sends the ChatMessage provided as an argument
     * ------------------------------------------------------------------------
     */
    public synchronized void sendMessage(ChatMessage msg) throws IOException
    {
        output.writeObject(msg);
    }
    
    /**
     * ------------------------------------------------------------------------
     * readMessage - reads the next ChatMessage off the input stream
     * ------------------------------------------------------------------------
     */
    public ChatMessage readMessage() throws IOException, ClassNotFoundException, SocketTimeoutException
    {
        return (ChatMessage) input.readObject();
    }
    
    /**
     * ------------------------------------------------------------------------
     * close - closes the socket and streams and handles any exceptions thrown
     * ------------------------------------------------------------------------
     */
    public void close()
    {
        try
        {
            output.close();
            input.close();
            connection.close();
        }
        catch(IOException ioException)
        {
            ioException.printStackTrace();
        }   
    }
}