import java.net.InetAddress;
import javax.media.CaptureDeviceInfo;
import javax.media.protocol.PushBufferDataSource;
import javax.media.protocol.PushBufferStream;
import javax.media.rtp.RTPManager;
import javax.media.rtp.SessionAddress;
import javax.media.rtp.SendStream;
import javax.media.rtp.rtcp.SourceDescription;

//clase que implementa un transmisor de audio
public class TransmisorAudio extends Transmisor// implements ReceiveStreamListener, RemoteListener, ControllerListener
{
	//constructor de la clase
	public TransmisorAudio(Target destino)
	{
		//inicializamos las variables
		super(destino);
	}

	//metodo que inicia la transmisión RTP
	public String start(CaptureDeviceInfo audio)
	{
		String aux;

		//calculamos el locator del dispositivo
		System.out.println(Misc.ind() + "Calculando locator");
		locator = audio.getLocator();

		//creamos un procesador para el dispositivo
		System.out.println(Misc.ind() + "Creando procesador");
		Misc.aumentarInd();
		if ((aux = crearProcesador()) != null)
		{
			System.out.println(Misc.ind() + "No se pudo crear el procesador:");
			Misc.aumentarInd();
			System.out.println(aux);
			Misc.reducirInd();
			Misc.reducirInd();
			return aux;
		}
		Misc.reducirInd();
		System.out.println(Misc.ind() + "Procesador creado");

		//creamos un transmisor
		System.out.println(Misc.ind() + "Creando transmisor");
		Misc.aumentarInd();
		if ((aux = crearTransmisor(destino)) != null)
		{
			System.out.println(Misc.ind() + "No se pudo crear el transmisor:");
			Misc.aumentarInd();
			System.out.println(Misc.ind() + aux);
			Misc.reducirInd();
			System.out.println(Misc.ind() + "Cerrando el procesador");
			Misc.reducirInd();
			//si no se pudo crear el transmisor, cerramos el procesador
			procesador.close();
			procesador = null;
			return aux;
		}
		Misc.reducirInd();
		System.out.println(Misc.ind() + "Transmisor creado");

		//iniciamos el procesador
		System.out.println(Misc.ind() + "Iniciamos el procesador");
		procesador.start();

		return null;
	}

	//metodo que crea un transmisor
	private String crearTransmisor(Target destino)
	{
		//creamos un buffer a partir del audio
		System.out.println(Misc.ind() + "Creando el buffer de salida de audio");
		PushBufferDataSource pbds = (PushBufferDataSource)salida;
		//obtenemos la lista de secuencias del buffer
		System.out.println(Misc.ind() + "Creando tabla de secuencias");
		PushBufferStream pbss[] = pbds.getStreams();
		//creamos una tabla de manejadores RTP
		System.out.println(Misc.ind() + "Creando tabla de manejadores RTP");
		rtpManagers = new RTPManager[pbss.length];
		//creamos una tabla de puertos locales de audio
		System.out.println(Misc.ind() + "Creando tabla de puertos locales");
		puertosLocales = new int[pbss.length];

		SessionAddress localAddr, destAddr;
		SendStream sendStream;
		int puerto;
		SourceDescription srcDesList[];

		//vamos recorriendo todas las secuencias
		System.out.println(Misc.ind() + "Recorremos todas las secuencias");
		Misc.aumentarInd();
		for (int i = 0; i < pbss.length; i++)
		{
			try
			{
				//creamos un nuevo manejador RTP
				System.out.println(Misc.ind() + "Creando manejador RTP " + i);
				rtpManagers[i] = RTPManager.newInstance();
				//añadimos un nuevo puerto
				System.out.print(Misc.ind() + "Creando puerto local RTP: ");
				puerto = (new Integer(destino.puertoAudioLocal()).intValue()) + 2 * i;
				System.out.println(puerto);
				puertosLocales[i] = puerto;
				//calculamos la IP local
				System.out.print(Misc.ind() + "Calculando la IP local: ");
				localAddr = new SessionAddress(InetAddress.getByName(destino.ipLocal()), puerto);
				System.out.println(localAddr.getDataAddress());
				//inicializamos el manejador RTP
				System.out.println(Misc.ind() + "Inicializando manejador RTP");
				rtpManagers[i].initialize(localAddr);
				rtpManagers[i].addReceiveStreamListener(this);
				rtpManagers[i].addRemoteListener(this);
				//añadimos un destino al manejador RTP
				System.out.println(Misc.ind() + "Anadiendo destino al manejador RTP");
				int targetPort = (new Integer(destino.puertoAudioLocal())).intValue();
				addTarget(puertosLocales[i], rtpManagers[i], destino.ipRemota(), targetPort + 2 * i);
				//Creamos una secuencia de envio
				System.out.println(Misc.ind() + "Creando secuencia de envio RTP");
				sendStream = rtpManagers[i].createSendStream(salida, i);
				//iniciamos la secuencia de envio
				sendStream.start();
			}
			//capturamos la excepción
			catch (Exception e)
			{
				Misc.reducirInd();
				e.printStackTrace();
				return e.getMessage();
			}
		}
		Misc.reducirInd();
		System.out.println(Misc.ind() + "Todas las secuencias recorridas");

		return null;
	}
}
