/**
 * 
 */
package com.beem.project.beem.jingle;

import java.util.ArrayList;
import java.util.List;

import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.JingleSession;
import org.jivesoftware.smackx.jingle.JingleSessionRequest;
import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener;
import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
import org.jivesoftware.smackx.jingle.media.PayloadType;
import org.jivesoftware.smackx.jingle.nat.BasicTransportManager;
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;

/**
 * @author nikita
 *
 */
public class JingleService {
    private JingleManager            mJingleManager;
    private List<JingleMediaManager> mMediaManagers;
    private JingleSession            mIn;
    private JingleSession            mOut;

    public JingleService(XMPPConnection xmppConnection) {
	BasicTransportManager bt = new BasicTransportManager();

	mMediaManagers = new ArrayList<JingleMediaManager>();
	mMediaManagers.add(new RTPMediaManager(bt));
    }

    public void initWhenConntected(XMPPConnection conn) {
	mJingleManager = new JingleManager(conn, mMediaManagers);
	mJingleManager.addJingleSessionRequestListener(new BeemJingleSessionRequestListener());
    }

    public void call(final String destinataire) {
	try {
	    mOut = mJingleManager.createOutgoingJingleSession(destinataire);
	    // TODO configure out avec addMediaSession et addNegociator
	    mOut.addListener(new BeemJingleCallerSessionListener());
	    mOut.startOutgoing();
	} catch (XMPPException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
    }

    /*
    private void receiveData(String ip, int port) throws IOException {
	Socket s = null;
	try {
	    s = new Socket(ip, port);
	    System.out.println("Waiting data");
	    InputStream in = s.getInputStream();
	    int a;
	    while ((a = in.read()) != -1) {
		System.out.println("Received " + a);
	    }
	    System.out.println("End receiving data");
	} finally {
	    if (s != null)
		s.close();
	}
    }*/
    
    private class BeemJingleReceiverSessionListener implements JingleSessionListener {
	 @Override
	    public void sessionClosed(String reason, JingleSession jingleSession) {
		System.out.println("Session " + jingleSession.getResponder() + "closedd because " + reason);
	    }

	    @Override
	    public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) {
		// TODO Auto-generated method stub
		System.out.println("Session " + jingleSession.getResponder() + " closed");

	    }

	    @Override
	    public void sessionDeclined(String reason, JingleSession jingleSession) {
		// TODO Auto-generated method stub
		System.out
		.println("Session " + jingleSession.getResponder() + "declined because " + reason);
	    }

	    @Override
	    public void sessionEstablished(PayloadType pt, TransportCandidate remoteCandidate,
		TransportCandidate localCandidate, JingleSession jingleSession) {
		System.out.println("Session established");
		System.out.println("Je recois sur " + remoteCandidate.getIp() + ":"
		+ remoteCandidate.getPort());
		RTPReceiver rtpReceiver = new MicroRTPReceiver(remoteCandidate.getPort());
	    }

	    @Override
	    public void sessionMediaReceived(JingleSession jingleSession, String participant) {
		System.out.println("Session Media received from " + participant);
	    }

	    @Override
	    public void sessionRedirected(String redirection, JingleSession jingleSession) {
	    }
    }

    private class BeemJingleCallerSessionListener implements JingleSessionListener {
	@Override
	public void sessionClosed(final String reason, final JingleSession jingleSession) {
	    System.out.println("Session " + jingleSession.getResponder() + "closed because " + reason);
	}

	@Override
	public void sessionClosedOnError(final XMPPException e, final JingleSession jingleSession) {
	    System.out.println("Session " + jingleSession.getResponder() + " closed on error");

	}

	@Override
	public void sessionDeclined(final String reason, final JingleSession jingleSession) {
	    System.out.println("Session " + jingleSession.getResponder() + "declined because " + reason);
	}

	@Override
	public void sessionEstablished(final PayloadType pt, final TransportCandidate remoteCandidate,
	    final TransportCandidate localCandidate, final JingleSession jingleSession) {
	    System.out.println("Session established");
	    // String name = localCandidate.getName();
	    String ip = localCandidate.getIp();
	    int port = localCandidate.getPort();
	    System.out.println("Session established waiting connection on " + ip + ":" + port);


	    RTPTransmitter transm = new MicroRTPTransmitter(ip, port);

	    transm.run();
	    try {
		Thread.sleep(20000);
	    } catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	    }
	    transm.stop();
	    System.out.println("End of transfer");

	}

	@Override
	public void sessionMediaReceived(final JingleSession jingleSession, final String participant) {
	    // TODO Auto-generated method stub
	    System.out.println("Session Media received from " + participant);
	}

	@Override
	public void sessionRedirected(final String redirection, final JingleSession jingleSession) {
	    // TODO Auto-generated method stub
	}
    }

    private class BeemJingleSessionRequestListener implements JingleSessionRequestListener {
	@Override
	public void sessionRequested(JingleSessionRequest request) {
	    System.out.println("Jingle Session request from " + request.getFrom());
	    try {
		mIn = request.accept();
		mIn.addListener(new BeemJingleReceiverSessionListener());
		mIn.startIncoming();
	    } catch (XMPPException e) {
		e.printStackTrace();
	    }
	}
    }

}
