package apps.conf;

import java.util.*;
import cnrg.itx.signal.*;
import cnrg.itx.signal.SignalEvent.*;
import cnrg.itx.datax.*;
import cnrg.itx.datax.devices.*;
import cnrg.itx.ds.*;

class DialManager implements SignalConnectionObserver{
	private ConnectionManager cm = null;
	public NetworkDestination netDest;
	public NetworkSource netSource;	
	public MixerChannel mixer;
	public Channel in;
	public Channel out;
	public SignalConnection conn;
	
	
	public DialManager(ConnectionManager cm, String uid, Location l) {
		this.cm = cm;
		mixer = cm.getConference().getMixer();
	
		try {
			netDest = new NetworkDestination(false); //don't use FEC and RTP: too much overhead
							
			// hook the mixer to feed into the net destination, 
			// get a channel from the mixer (in) to feed data into
			if (cm.getHearSelf()) {
				mixer.addDestination(netDest);
				in = mixer.getNewInput();
			}else {
				in = mixer.getNewSubtractedInput(netDest);
			}	
			
			//Get a net source w/o FEC or RTP
			netSource = new NetworkSource(in,SpeakerDestination.SAMPLE_SIZE, false);
			
			//set the net source to feed into the mixer's input
			in.setSource(netSource);
			
			
			//We only show signaling this DummyChannel so it can configure
			//its destination (netDest) without hurting netDest's real source: the mixer
			
			//The DummyChannel conveys all propery, open, and close messages like

			out =new DummyChannel();
			out.addDestination(netDest);
			//Keep everyone happy by giving out fake channel a fake source.
			out.setSource(new DummySource());
				
			conn =	cm.getDesktopSignaling().Dial(uid,l,in,out,this);
			conn.startCall();
			
			
				
		} catch (DataException de) {
			de.printStackTrace();
			close();
		} catch (DesktopSignalingException dse) {
			dse.printStackTrace();
			close();
		}	
		
	}
	
	public void close() {
		
		try { 
			conn.abortCall();
		} catch (Exception e) {}
		
		
		if (mixer != null) {
			mixer.removeDestination(netDest); //remove the participant from the mixer's output
		
			if (in != null) {
				mixer.removeInput(in); //closes "in" and "netSource";
			}
		}
		
		if (netSource != null)
			netSource.close();
		
		cm.removeDialManager(this);
		
	}
	
	
	/* *********** SignalConnectionObserver interface Support ***************/
	
	
	/**
	 * Called when the dialed participant accepts the invitation.
	 */
	public void onAccept(DialSignalEvent dse){
		if (!cm.accept(dse, this)) {
			//dse.getSignalConnection().abortCall();
			close();
		}
			
	}
	/**
	 * closes connection
	 */
	public void onReject(DialSignalEvent dse){
		close(); 
		System.out.print("Connection rejected: ");
		System.out.println(dse);
	}
	/**
	 * closes connection
	 */
	public void onBusy(DialSignalEvent dse){
		close(); 
		System.out.print("Busy: ");
		System.out.println(dse);
	}
	/**
	 * closes connection
	 */
	public void onInvalid(DialSignalEvent dse){
		close(); 
		System.out.print("Connection Invalid: ");
		System.out.println(dse);
	}
	/**
	 * closes connection
	 */
	public void onTimeout(DialSignalEvent dse){
		close(); 
		System.out.print("Connection timed out: ");
		System.out.println(dse);
	}
	/**
	 * closes connection
	 */
	public void onIncompatible(DialSignalEvent dse){
		close(); 
		System.out.print("Connection Incompatable: ");
		System.out.println(dse);
	}
	/**
	 * closes connection
	 */
	public void onError(DesktopSignalingException dse){
		close(); 
		System.out.print("Connection Error: ");
		System.out.println(dse);
	}
}
