/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package rsx.tcp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 *
 * @author loquicom
 */
public class TcpClient {

    /**
     * Adresse du serveur
     */
    protected InetAddress adr;

    /**
     * Port du serveur
     */
    protected int port;

    /**
     * Socket TCP
     */
    protected Socket socket;

    /**
     * Timeout de la socket (en milisecondes)
     */
    protected int timeout = 0;

    /**
     * Flux d'entrée
     */
    protected BufferedReader input;

    /**
     * Flux de sorti
     */
    protected PrintWriter output;

    /* --- Constructeurs --- */
    /**
     * Creation d'un client TCP
     *
     * @param ip L'ip du serveur
     * @param port Le port du serveur
     * @throws UnknownHostException
     */
    public TcpClient(String ip, int port) throws UnknownHostException {
        this.adr = InetAddress.getByName(ip);
        this.port = port;
    }

    /**
     * Creation d'un client TCP
     *
     * @param adr L'adresse du serveur
     * @param port Le port du serveur
     */
    public TcpClient(InetAddress adr, int port) {
        this.adr = adr;
        this.port = port;
    }

    /* --- Methodes --- */
    /**
     * Temps avant timeout du receive (qui retournera false)
     * @param second Le temps en senconde
     */
    public void timeout(int second) {
        this.timeout = second * 1000;
    }

    /**
     * Retire un timeout
     */
    public void notimeout() {
        this.timeout = 0;
    }

    /**
     * Connexion au serveur
     *
     * @return Reussite
     */
    public boolean connect() {
        try {
            this.socket = new Socket(this.adr, this.port);
            //Si un timeout
            if (this.timeout > 0) {
                this.socket.setSoTimeout(this.timeout);
            }
            //Ouverture flux
            this.input = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
            this.output = new PrintWriter(this.socket.getOutputStream());
        } catch (IOException ex) {
            System.err.println("Impossible de se connecter au serveur : " + ex.getMessage());
            return false;
        }
        return true;
    }

    /**
     * Envoi message au serveur
     *
     * @param msg Le message
     * @return Reussite
     */
    public boolean send(String msg) {
        output.print(msg);
        output.flush();
        return true;
    }

    /**
     * Reception d'un message du serveur
     *
     * @return Le message ou null en cas d'erreur
     */
    public String receive() {
        try {
            return input.readLine();
        } catch (IOException ex) {
            //Si pas l'exception du timeout
            if (!ex.getMessage().equals("Read timed out")) {
                System.err.println("Impossible de lire : " + ex.getMessage() + " ");
            }
            return null;
        }
    }

    /**
     * Ferme la connexion au serveur
     *
     * @return Reussite
     */
    public boolean close() {
        try {
            input.close();
            output.close();
            socket.close();
        } catch (IOException ex) {
            System.err.println("Impossible de de fermer le client : " + ex.getMessage());
            return false;
        }
        return true;
    }

    /* --- Getter/Setter --- */
    public InetAddress getAdr() {
        return adr;
    }

    public void setAdr(InetAddress adr) {
        this.adr = adr;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

}
