import java.net.*;
import java.io.*;
import javax.swing.*;

/**
 * Clase encargada del manejo de todo lo relacionado con la conexion por
 * internet: creacion de socket, comprobar que es un servidor de KaBoom
 */
public class Connection
{
   /**
    * Indica si se esta conectado a algun servidor valido.
    */
   private boolean connected = false;
   
   /**
    * Direccion del servidor.
    */
   private String  servAddr;
   
   /**
    * Puerto.
    */
   private int port;
   
   /**
    * Socket.
    */
   private Socket  socket;
   
   /**
    * Buffer de entrada. Comandos recibidos desde el servidor.
    */
   private BufferedReader inCmd;
   
   /**
    * Buffer de salida. Comandos a enviar al servidor.
    */
   private PrintWriter    outCmd;
   
   /**
    * Constructor.
    */
   public Connection()
   {}
   
   /**
    * Establece una conexion con el servidor 'addr' al puerto 'port'. Si el
    * parametro 'addr' es igual a "console" se podra usar la consola como si
    * esta fuera un servidor, para fines de depuracion.
    * @param addr Direccion del servidor, puede ser el nombre o la IP.
    * @param port Puerto.
    * @return "exception" : Si ocurre una excepcion.
    *         "wrongserver" : Si no es un servidor de KaBoom.
    *         "success" : Si la conexion se establecio exitosamente.
    */
   public String connect(String addr, int port)
   {
      if (connected)
      {
         try
         {
            socket.close();
            connected = false;
         }
         catch(Exception e)
         {
            System.out.println("Error cerrando el socket");
            System.exit(-1);
         }
      }
      
      if (addr.equals("console"))
      {
         inCmd = new BufferedReader(new InputStreamReader(System.in));
         outCmd = new PrintWriter(System.out, true /* autoFlush */);
         connected = true;
      }
      else
      {
         try
         {
            socket = new Socket(addr, port);
            inCmd = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            outCmd = new PrintWriter(socket.getOutputStream(), true /* autoFlush */);
         }
         catch(Exception e)
         {
            return "exception";
         }
         String data = recv(true);
         if (!data.equals("Bienvenido a KaServer"))
            return "wrongserver";
         else
            connected = true;
      }
      
      servAddr = addr;
      this.port = port;
      return "success";
   }
   
   /**
    * Envia un comando al servidor.
    * @param str El comando a enviar;
    */
   public void send(String str)
   {
      outCmd.println(str);
   }
   
   /**
    * Recibe comandos desde el servidor.
    * @param blockingRead True: si se desea una lectura bloqueante.
    *                     False: si se desea una lectura no bloqueante.
    * @return El comando recibido.
    */
   public String recv(boolean blockingRead)
   {
      try
      {
         if (inCmd.ready() || blockingRead)
         {
            return inCmd.readLine();
         }
      }
      catch (IOException e)
      {
         System.exit(-1);
      }
      
      return null;
   }
   
   /**
    * Indica si hay una conexion valida establecida.
    * @return True: Si se esta conectado a algun servidor valido.
    *         False: Si no hay conexiones establecidas.
    */
   public boolean isConnected()
   {
      return connected;
   }
}
