import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;

//clase que maneja una configuración
public class Config
{
	//constantes de la clase
	private static final String ARCHIVO = "conf.dat";

	//variables miembro de la clase
	private String pathPrefix;
	private Target destino;

	//constructor de la clase
	public Config()
	{
		//obtenemos el directorio home del usuario
		pathPrefix = System.getProperty("user.home") + File.separator;
		System.out.println(Misc.ind() + "Directorio de usuario: '" + pathPrefix + "'");
		//leemos la configuración de disco
		read();
	}

	//método que lee la configuración del disco
	public void read()
	{
		//añadimos el nombre del archivo a la ruta
		String path = pathPrefix + ARCHIVO;
		System.out.println(Misc.ind() + "Usando fichero de configuracion: '" + path + "'");
		try
		{
			//abrimos el archivo para lectura
			FileInputStream fin = new FileInputStream(path);
			//creamos un buffer de entrada
			BufferedInputStream bin = new BufferedInputStream(fin);
			//creamos una secuencia de datos a partir del buffer
			DataInputStream din = new DataInputStream(bin);
			//leemos de disco los datos y los almacenamos
			destino = new Target(readString(din), readString(din), readString(din), readString(din), readString(din), readString(din));
			//cerramos el archivo
	        fin.close();
		}
		//capturamos la excepcion
		catch (FileNotFoundException e)
		{
			//creamos unos datos por defecto
			System.out.println(Misc.ind() + "¡No se encuentra el archivo 'conf.dat'!");
			destino = new Target();
		}
		//capturamos la excepcion
		catch(IOException e)
		{
			// creamos unos datos por defecto
			System.out.println(Misc.ind() + "¡No se encuentra el archivo 'conf.dat'!");
			destino = new Target();
		}
		System.out.println(Misc.ind() + "Dirección IP local: " + destino.ipLocal());
		System.out.println(Misc.ind() + "Puerto de audio local: " + destino.puertoAudioLocal());
		System.out.println(Misc.ind() + "Puerto de video local: " + destino.puertoVideoLocal());
		System.out.println(Misc.ind() + "Direccion IP remota: " + destino.ipRemota());
		System.out.println(Misc.ind() + "Puerto de audio remoto: " + destino.puertoAudioRemoto());
		System.out.println(Misc.ind() + "Puerto de video remoto: " + destino.puertoVideoRemoto());
	}

	//método que guarda la configuración a disco
	public void write()
	{
		//añadimos el nombre del archivo a la ruta
		String path = pathPrefix + ARCHIVO;
		System.out.println(Misc.ind() + "Usando fichero de configuracion: '" + path + "'");
		try
		{
			//abrimos el fichero para escritura
			FileOutputStream fout = new FileOutputStream(path);
			//creamos un buffer de escritura
			BufferedOutputStream bout = new BufferedOutputStream(fout);
			//creamos una secuencia de escritura
			DataOutputStream dout = new DataOutputStream(bout);
			//escribimos los valores a disco
			writeString(dout, destino.ipLocal());
			System.out.println(Misc.ind() + "Direccion IP local: " + destino.ipLocal());
			writeString(dout, destino.puertoAudioLocal());
			System.out.println(Misc.ind() + "Puerto de audio local: " + destino.puertoAudioLocal());
			writeString(dout, destino.puertoVideoLocal());
			System.out.println(Misc.ind() + "Puerto de video local: " + destino.puertoVideoLocal());
			writeString(dout, destino.ipRemota());
			System.out.println(Misc.ind() + "Direccion IP remota: " + destino.ipRemota());
			writeString(dout, destino.puertoAudioRemoto());
			System.out.println(Misc.ind() + "Puerto de audio remoto: " + destino.puertoAudioRemoto());
			writeString(dout, destino.puertoVideoRemoto());
			System.out.println(Misc.ind() + "Puerto de video remoto: " + destino.puertoVideoRemoto());
			//limpiamos la secuencia de salida
			dout.flush();
			//limpiamos el buffer
			dout.close();
			//cerramos el archivo
			fout.close();
		}
		//capturamos la excepcion
		catch( IOException e)
		{
			System.out.println("¡Error escribiendo el archivo 'conf.dat'!");
		}
	}

	//método que devuelve la configuración
	public Target destino() { return destino; }

	//metodo que lee una cadena de disco
	public String readString(DataInputStream din)
	{
		String s = null;

		try
		{
			//leemos la longitud de la cadena
			short length = din.readShort();
			//si la longitud > 0, leemos la cadena
			if(length > 0)
			{
				byte buf[] = new byte[length];
				din.read(buf, 0, length);
				s = new String(buf);
			}
		}
		//capturamos la excepcion
		catch(IOException e)
		{
			System.err.println( e);
		}

		return s;
	}

	//metodo que escribe una cadena en disco
	public void writeString(DataOutputStream dout, String str)
	{
		try
		{
			//si la cadena existe
			if(str != null)
			{
				//escribimos la longitud de la cadena
				dout.writeShort(str.length());
				//escribimos la cadena
				dout.writeBytes(str);
			}
			//en caso contrario, escribimos 0
			else
				dout.writeShort(0);
		}
		//capturamos la excepcion
		catch( Exception e)
		{
			e.printStackTrace();
		}
	}
}



