package examples.example2_one_client_OO;

import java.io.IOException;
import java.net.BindException;
import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.net.SocketException;
import java.net.UnknownHostException;

import javax.swing.JOptionPane;

/**
 * <pre>
 * NetworkingExamples project: examples.example2_one_client_OO.
 * 
 * A simple example of networking (Sockets) in which:
 *   -- A single Server and Client exchange information, one after the other.
 * 
 * This is the same example as {@link examples.example1_one_client}
 * except structured in a more OO way.  In particular, this structure has 3 classes:
 *   -- Main: for starting the program.
 *   -- Server: for initiating and running the Server.
 *   -- Client: for initiating and running the Client.
 * 
 * Run this program on one computer choosing "Server"
 * and on another computer choosing "Client".
 * 
 * Or, run both on the same computer; choose "localhost" as the Server HostName.
 * 
 * NOTE:
 *   1. The Server should be started before the Client starts.
 *   2. Before running this program, you may need to tell your Firewall not to
 *      block the port that this program uses (4444, chosen arbitrarily).  In Windows, do so by:
 *         Control Panel ~ Windows Firewall ~ Exceptions tab ~ Add Port
 *      and enter the port number (4444) with any name you like.
 *      
 * See {@link examples.example1_one_client#MainForServer} for:
 *   -- Exactly what information the Server and Client exchange in this demo.
 *   -- The 7 Key Statements that are all-you-need-to-know to do networking in Java.
 *   
 * See {@link examples.example3_one_client_OO_library} for this same example
 * but using the simple networking library in package {@link simpleNetworking}.
 * </pre>
 * 
 * @author David Mutchler, based on the Java Tutorials on networking. May, 2009.
 */
public class Main {
	private static int PORT = 4444; // most numbers > 1023 are probably OK here

	/**
	 * Asks the user whether she wishes to be the Server or Client,
	 * and constructs whichever she requests.
	 *
	 * @param commandLineArguments Ignored here
	 */
	public static void main(String[] commandLineArguments) {
		String hostName = "";
		String whoAmI = "";
		
		try {
			String[] options = {"Server", "Client"};
			int answer = JOptionPane.showOptionDialog(
					null,
					"Are you the Server or the Client?\n\n"
					+ "Remember to start the Server before the Client.\n\n",
					"Which are you -- Server or Client?",
					JOptionPane.YES_NO_OPTION,
					JOptionPane.QUESTION_MESSAGE,
					null,
					options,
					"Server");

			if (answer == 0) {
				whoAmI = "Server";
				
				new Server(Main.PORT);

			} else {
				whoAmI = "Client";
				
				hostName = JOptionPane.showInputDialog(
						"OK, you are the Client and have started.\n\n"
						+ "What is the HostName (e.g. mutchler-3.rose-hulman.edu)\n"
						+ "or IP address (e.g. 137.112.40.1) of the Server?\n"
						+ "(Enter   localhost   or just press OK for this local machine.)\n\n");
				new Client(hostName, Main.PORT);
			}
			
		} catch (UnknownHostException exception) {
			System.out.println(exception);
			JOptionPane.showMessageDialog(null,
					whoAmI + " could not connect to   " + hostName
					+ "    because that is an unknown host.\n\n"
					+ "The Server may still running; fix that by running a Client\n"
					+ "(without starting a Server).\n\n");

		} catch (ConnectException exception) {
			System.out.println(exception);
			JOptionPane.showMessageDialog(null,
					whoAmI + " could not connect to   " + hostName
					+ "   either because:\n"
					+ " -- the Server is not yet started, or \n"
					+ " -- the host does not accept connections on port " + Main.PORT + ".\n\n"
					+ "The Server may still running; fix that by running a Client\n"
					+ "(without starting a Server).\n\n");

		} catch (NoRouteToHostException exception) {
			System.out.println(exception);
			JOptionPane.showMessageDialog(null,
					whoAmI + " could not connect to   " + hostName
					+ "   perhaps because\n"
					+ "the hostname   " + hostName
					+ "   does not allow connections on port   " + Main.PORT + ".\n\n"
					+ "The Server may still running; fix that by running a Client\n"
					+ "(without starting a Server).\n\n");

		} catch (BindException exception) {
			System.out.println(exception);
			JOptionPane.showMessageDialog(null,
					whoAmI + " could not connect to   " + hostName
					+ "   perhaps because\n"
					+ "port   " + Main.PORT + "   is in use.\n"
					+ "The Server is probably still running; stop it by getting a Client to run.\n\n"
					+ "The Server may still running; fix that by running a Client\n"
					+ "(without starting a Server).\n\n");

		} catch (SocketException exception) {
			System.out.println(exception);
			JOptionPane.showMessageDialog(null,
					whoAmI + " ended, either because it could not start\n"
					+ "or (more likely) because the user closed the Server.\n\n");

		} catch (IOException exception) {
			System.out.println(exception);
			JOptionPane.showMessageDialog(null,
					whoAmI + " ended, probably because the user closed the Server.\n\n");
		}

		catch (Throwable exception) {
			System.out.println(exception);
			JOptionPane.showMessageDialog(null, whoAmI + " ended abnormally.  See stack trace.\n\n");
			exception.printStackTrace();
		}
	}
}