
// ChatServerHandler.java
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th
/*
   Toto vlákno řeší požadavky klienta.

   Údaje o každém klientovi udržuje v objektu typu ChatGroup,
   na který se odkazuje každé vlákno.

   Objekt typu ChatGroup řeší rozesílání zpráv pomocí metody 
   broadcast().

   Možné zprávy klientů:
 	who		-- vrátí seznam uživatelů
        bye     	-- klient se odpojuje
	jakýkoli text	-- který se rozešle všem s hlavičkou "(cliAddr,port):"
*/

import java.net.*;
import java.io.*;


public class ChatServerHandler extends Thread
{
  private Socket clientSock;    // údaje o klientovi
  private String cliAddr;
  private int port;

  private ChatGroup cg;    // sdílí všechna vlákna


  public ChatServerHandler(Socket s, ChatGroup cg)
  {
    this.cg = cg;
    clientSock = s;
    cliAddr = clientSock.getInetAddress().getHostAddress();
    port = clientSock.getPort();
    System.out.println("Spojení od klienta z adresy (" + 
						cliAddr + ", " + port + ")");
  } // konec metody: ChatServerHandler()


  public void run()
  {
    try {
      // Získej V/V proudy ze socket
      BufferedReader in  = new BufferedReader( 
	  		new InputStreamReader( clientSock.getInputStream() ) );
      PrintWriter out = 
			new PrintWriter( clientSock.getOutputStream(), true );  // autoflush

      cg.addmerson(cliAddr, port, out);  // přidej údaje o klientovi do objektu typu ChatGroup
      processClient(in, out);            // komunikuj s klientem
 
      // tady již klient svou komunikaci ukončil
      cg.delPerson(cliAddr, port);       // odeber údaje o klientovi
      clientSock.close();
      System.out.println("Klient (" + cliAddr + ", " + port + ") spojení uzavřeno\n");
    }
    catch(Exception e)
    {  System.out.println(e);  }
  }  // konec metody: run()


   private void processClient(BufferedReader in, PrintWriter out)
   /* Zastav, jakmile se uzavře vstupní proud (má hodnotu null) nebo 
      přijde zpráva "bye". Jinak předej vstup metodě doRequest(). */
   {
     String line;
     boolean done = false;
     try {
       while (!done) {
         if((line = in.readLine()) == null)
           done = true;
         else {
           System.out.println("Klient (" + cliAddr + ", " + port + "): " + line);
           if (line.trim().equals("bye"))
             done = true;
           else 
             doRequest(line, out);
         }
       }
     }
     catch(IOException e)
     {  System.out.println(e);  }
   }  // konec metody: processClient()


  private void doRequest(String line, PrintWriter out)
  /*  Vstupní řádek (zpráva klienta) může být:
	who		-- vrátí seznam uživatelů
        bye     	-- klient se odpojuje
	jakýkoli text	-- který se rozešle všem s hlavičkou "(cliAddr,port):"
  */
  { if (line.trim().toLowerCase().equals("who")) {
      System.out.println("Zpracovávám 'who'");
      out.println( cg.who() );
    }
    else  // pro rozeslání zprávy použij objekt typu ChatGroup
      cg.broadcast( "("+cliAddr+", "+port+"): " + line);
  }  // konec metody: doRequest()


}  // konec třídy: ChatServerHandler

