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

/**
 * Le client peu exigeant.  Il demande une connexion sur une soquette et envoie
 * un simple message d'amitié.  
 * <P>
 * C'est une << appletication >> (marche aussi bien en applet qu'en application).
 *
 * @author Peter T. Sander
 * @version 1.0  1/10/96
 */

public class ClientSimple extends java.applet.Applet {
  private static final boolean AS_APPLET = true;  // par défaut
  private boolean asApplet;
  private static final InetAddress HOTE = null;
  private InetAddress hote;
  private static final int PORT = 6666;  // par défaut
  private int port;
	
  /**
    * No-args constructeur.  Utilise le port 6666 sur la machine locale
    * par défaut.
    * <P>
    * Seulement les applets passent par ici.
    */
  public ClientSimple() {
    this(HOTE, PORT, AS_APPLET);
  }
	
  /**
    * Constructeur.  Utilise le port 6666 sur la machine locale par défaut.
    * <P>
    * Seulement les applications passent par ici.
    *
    * @param asApplet applet ou application ?
    */
  public ClientSimple(boolean asApplet) {
    this(HOTE, PORT, asApplet);
  }
	
  /**
    * Constructeur.  Les applets et les applications passent par ici toutes
    * les deux.
    *
    * @param hote la machine hote du serveur
    * @param port le port où les clients viendront s'attacher
    * @param asApplet applet ou application ?
    */
  public ClientSimple(InetAddress hote, int port, boolean asApplet) {
    super();
    this.asApplet = asApplet;
    this.hote = hote;
    this.port = port;

    if (!this.asApplet) {
      if (this.hote == null) {
	try {
	  this.hote = InetAddress.getLocalHost();
	} catch (UnknownHostException e) {
	  e.printStackTrace();
	}
      }
      start();
    }
  }

  /**
    * Initialise l'applet.  Les applications ne passent pas par ici.
    */
  public void init() {
    String hoteNom = getParameter("hote");

    try {

      if (hoteNom == null) {
	hote = InetAddress.getByName(getCodeBase().getHost());
      } else {
	hote = InetAddress.getByName(hoteNom);
      }

    } catch (UnknownHostException e) {
      System.err.println("Impossible de déterminer l'adresse IP du hote");
      System.err.println(e);
      return;  // aucune raison de traîner par ici
    }
    try {
      port = Integer.parseInt(getParameter("port"));
    } catch (NumberFormatException e) {
      port = PORT;
    }
  }

  /**
    * La méthode qui fait le boulot.  Elle ouvre une soquette vers un serveur,
    * reçoit son message d'acceuil, lui envoie une réplique et ferme
    * la connexion.
    */
  public void start() {
    Socket soquette = null;

    try {
      // ouvre une connexion sur le port du serveur
      soquette = new Socket(hote, port);

      // associe un flot en entrée à la soquette
      BufferedReader in = new BufferedReader(new InputStreamReader(soquette.getInputStream()));

      // et un flot en sortie
      PrintWriter out = new PrintWriter(soquette.getOutputStream());

      // reçoit le message d'accueil du serveur
      System.out.println("Le serveur m'a dit : " + in.readLine());

      // et envoie la riposte
      out.println("Et ta mère...");
      out.flush();
    } catch (IOException e) {
      System.err.println("Opération foireuse sur la soquette : " + e);
    } finally {

      try {
	if (soquette != null) {
	  // et on ferme cette connexion
	  soquette.close();
	}
      } catch (IOException e) {}
    }
  }
	
  /**
    * La méthode principale d'une application.
    * <P>
    * Le nom de la machine et le no. du port sont des arguments 
    * optionels à l'application.
    *
    * @param args lezarguments
    */
  public static void main(String[] args) throws NumberFormatException,
    UnknownHostException {

    // ne fait aucune vérification des arguments
    if (args.length == 2) {
      new ClientSimple(InetAddress.getByName(args[0]),
		       Integer.parseInt(args[1]), !AS_APPLET);
    } else {
      new ClientSimple(!AS_APPLET);
    }
  }
}
