import ReceptorEventos;

import java.net.*;
import java.io.*;

public class Oyente implements Runnable  {

   public static final int puerto = 4321;

   ReceptorEventos jefe;
   Socket canal = null;
   DataInputStream canalEntrada = null;
   DataOutputStream canalSalida = null;
   Thread hilo = null;
   boolean conectado = false;

   public Oyente( ReceptorEventos jefe )
   {
      this.jefe = jefe;
   }

   public boolean conectar( Socket s )
   {
     desconectar();
     try {
       canal = s;
       canalEntrada = new DataInputStream( canal.getInputStream() );
       canalSalida = new DataOutputStream( canal.getOutputStream() );
       hilo = new Thread(this);
       hilo.start();
       conectado = true;
       return(true);
     } catch(Exception e) {
       return(false);
     }
   }

   public boolean conectar( String host )
   {
     desconectar();
     try {
       canal = new Socket(host,puerto);
       canalEntrada = new DataInputStream( canal.getInputStream() );
       canalSalida = new DataOutputStream( canal.getOutputStream() );
       hilo = new Thread(this);
       hilo.start();
       conectado = true;
       return(true);
     } catch(Exception e) {
       return(false);
     }
   }

   public void desconectar()
   {
      if((hilo!=null) && hilo.isAlive()) hilo.stop();
      if(canalEntrada!=null) try { canalEntrada.close(); } catch(Exception e) {};
      if(canalSalida!=null) try { canalSalida.close(); } catch(Exception e) {};
      if(canal!=null) try { canal.close(); } catch(Exception e) {};
      conectado = false;
   }

   public void enviarEvento( int idEvt, String[] args )
   {
      int n = (args==null) ? 0 : args.length;
      try {
        canalSalida.writeInt(idEvt);
        canalSalida.writeInt(n);
        for(int i=0; i<n; i++) canalSalida.writeUTF(args[i]);
      } catch(IOException e) {
        jefe.nuevoEvento(this,ReceptorEventos.EVT_CORTE,null);
        desconectar();
      }
   }

   public boolean recibirEvento( )
   {
      try {
        int idEvt = canalEntrada.readInt();
        int n = canalEntrada.readInt();
        if(n==0) {
          jefe.nuevoEvento(this,idEvt,null);
          return(true);
        }
        String[] args = new String[n];
        for(int i=0; i<n; i++) args[i] = canalEntrada.readUTF();
        jefe.nuevoEvento(this,idEvt,args);
        return(true);
      } catch(IOException e) {
        jefe.nuevoEvento(this,ReceptorEventos.EVT_CORTE,null);
        desconectar();
        return(false);
      }
   }

   public void run( )
   {
      while( recibirEvento() );
   }

   public String toString( )
   {
      return(canal.getInetAddress().toString());
   }
}
