package com.flyingbuffalo.wfdmanager;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import android.net.wifi.p2p.WifiP2pInfo;
import android.os.AsyncTask;

/**
 * Paired WiFi direct device info. Wrapping origin object for library.
 * @author Shin
 *
 */
public class WFDPairInfo {

	public WifiP2pInfo info;
	
	public final static int PORT = 8988;
	public final static int SOCKET_TIMEOUT = 10000;
	public int port = PORT;
	public int socket_timeout = SOCKET_TIMEOUT;
	
	protected PairSocketConnectedListener pairSocketConnectedListener;
	
	/**
	 * Constructor WFDPairInfo
	 * @param i WifiP2pInfo
	 */
	public WFDPairInfo(WifiP2pInfo i) {
		this.info = i;
	}

	public String getLocalAddress() throws UnknownHostException {
		return InetAddress.getLocalHost().toString();
	}
	
	public String getRemoteAddress() {
		return info.groupOwnerAddress.getHostAddress();				
	}		
	
	/**
	 * Request to connect socket, to return socket.
	 * Socket is returned on onSocketConnected.
	 */	
	@Deprecated 
	public void getSocket() {
		ConnectionAsyncTask conTask = new ConnectionAsyncTask(info);
        conTask.execute();        
	}
	
	/**
	 * .
	 * Set PairSocketConnectedListener and Request to connect socket, to return socket through listener.
	 * Socket is returned on onSocketConnected.
	 * @param l PairSocketConnectedListener
	 */
	public void connectSocketAsync(PairSocketConnectedListener l) {
		this.pairSocketConnectedListener = l;
		
		ConnectionAsyncTask conTask = new ConnectionAsyncTask(info);
        conTask.execute();    
	}
	
	/**
	 * To getting socket, using this listener.
	 * @author Shin
	 *
	 */
	public interface PairSocketConnectedListener {
        public void onSocketConnected(Socket s);
	}
	
	 // After the group negotiation, we assign the group owner as the file
    // server. The file server is single threaded, single connection server
    // socket.
	private class ConnectionAsyncTask extends AsyncTask<Void, Void, String> {
		
		private WifiP2pInfo info;
		
		public ConnectionAsyncTask(WifiP2pInfo i) {
			this.info = i;
        }

		@Override
		protected String doInBackground(Void... params) {
			try {
				if (info.groupFormed && info.isGroupOwner) {
		        	ServerSocket serverSocket = new ServerSocket(PORT);
		        	Socket client = serverSocket.accept();
		        	pairSocketConnectedListener.onSocketConnected(client);
		        } else if (info.groupFormed) {
		        	String host = info.groupOwnerAddress.getHostAddress();		        
		        	
		        	Socket socket = new Socket();		        
					socket.bind(null);
		            socket.connect((new InetSocketAddress(host, port)), socket_timeout);
		            pairSocketConnectedListener.onSocketConnected(socket);
		        }	
	        } catch (IOException e) {				
				e.printStackTrace();
			}
			return null;
		}				
	}
}

@@ -286,16 +286,41 @@
 yncTask;
+%0Aimport android.util.Log;
 %0A%0A/**%0A *
@@ -2285,13 +2285,57 @@
 %0A%09%09%09
-try %7B
+ServerSocket serverSocket = null;%0A%09%09%09try %7B%09%09%09%09%09%09%09
 %0A%09%09%09
@@ -2382,26 +2382,24 @@
 er) %7B%0A%09%09
-        %09S
+%09%09%09if (s
 erverSoc
@@ -2394,32 +2394,49 @@
 f (serverSocket 
+== null) %7B%0A%09%09%09%09%09%09
 serverSocket = n
@@ -2455,15 +2455,120 @@
 ket(
+);%0A%09%09%09%09%09%09serverSocket.setReuseAddress(true);%0A%09%09%09%09%09%09serverSocket.bind(new InetSocketAddress(
 PORT)
+)
 ;%0A
+%09%09%09%09%09%7D%0A%09%09%09%09%09%0A
 %09%09  
@@ -3112,24 +3112,251 @@
 race();%0A%09%09%09%7D
+ %0A//%09%09%09finally %7B%0A//%09%09%09%09if(serverSocket != null)%0A//%09%09%09%09%09try %7B%09%09%09%09%09%09%0A//%09%09%09%09%09%09serverSocket.close();%0A//%09%09%09%09%09%09Log.d(%22FILE_TEST%22, %22Server socket closed%22);%0A//%09%09%09%09%09%7D catch (IOException e) %7B %0A//%09%09%09%09%09%09e.printStackTrace();%0A//%09%09%09%09%09%7D%0A//%09%09%09%7D
 %0A%09%09%09return n

reuse address true