package ftp_client;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;

// Classe simplifiant les communications par Socket, integrant directement les flux d'entrée/sortie
public class MSocket extends Socket {
	/* Encoding */
	// Encodage par defaut
	public static final String encoding = "UTF-8";
	
	/* Streams */
	private BufferedReader reader;
	private BufferedWriter writer;
	
	/* Constructor */
	public MSocket(String host, int port) throws UnknownHostException, IOException{
		super(host, port);
		reader = new BufferedReader(new InputStreamReader (this.getInputStream(),  encoding));
	    writer = new BufferedWriter(new OutputStreamWriter(this.getOutputStream(), encoding));
	}
	
	/* Communications */
	// Envoi d'une ligne
	public synchronized void sendLine(String line) throws IOException {
		writer.write(line + "\r\n");
		writer.flush();
		fireSendListener(line);
	}	

	// Lecture d'une ligne
	public synchronized String readLine() throws IOException {
		String line = reader.readLine();
		fireRecvListener(line);
		return line;
	}

	// Lecture de tout le texte disponible
	public synchronized String readAllText() throws IOException {
		String lines = "";		
		while(reader.ready()) lines += "\r\n" + reader.readLine();		
		if(lines.isEmpty())	return lines;
		lines = lines.substring(2);
		fireRecvListener(lines);		
		return lines;
	}

	
	/* Communications Event */
	// Ecouteur pour ceux qui veulent suivre toutes les communications sendLine(), readLine(), readAllText()
	public interface CommunicationListener {
		void communicationEvent(String message);
	}

	private static final Collection<CommunicationListener> sendListeners	= new ArrayList<CommunicationListener>();
	private static final Collection<CommunicationListener> recvListeners = new ArrayList<CommunicationListener>();

	protected static void fireSendListener(final String message) {
	   for(CommunicationListener listener : sendListeners)
		   listener.communicationEvent(message);
	}

	protected static void fireRecvListener(final String message) {
	   for(CommunicationListener listener : recvListeners)
		   listener.communicationEvent(message);
	}

	public static void addSendListener(CommunicationListener listener) {
		sendListeners.add(listener);
	}

	public static void removeSendListener(CommunicationListener listener) {
		sendListeners.remove(listener);
	}

	public static void addRecvListener(CommunicationListener listener) {
		recvListeners.add(listener);
	}

	public static void removeRecvListener(CommunicationListener listener) {
		recvListeners.remove(listener);
	}
}
