/*
 * The interface object serves as the go-between for the user and the
 * other objects.  It provides a gui that consists of three windows;
 * one that displays sent and received messages, another that displays
 * people on and offline, and a third that provides a group of
 * commands the user can use including preferences, security, etc.
 *
 * The interface is set up so that a user can close the network and
 * command windows and reopen them with the command window.  This
 * serves to clear up space on the desktop.  The program doesn't exit
 * until the message window is closed or the exit button on the
 * command window is pressed.
 */

import java.io.*;
import java.util.*;
import java.net.*;
import java.util.*;
import java.lang.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;

public class Interface {
    
    /* these are to keep track of whether the windows are open.  We
	 don't want to open up more than one of the same type of
	 window because that will be confusing. */
    private int MesWinOpen = 0;
    private int ComWinOpen = 0;
    private int NetWinOpen = 0;

      /* labels for windows and text */
      public final JLabel Commands = new JLabel("Available commands:");
      public final JLabel OnList = new JLabel("People On");
      public final JLabel OffList = new JLabel("People Off");
      public final String SendMessage = "Send";
      public final JLabel SendLabel = new JLabel(SendMessage);
      
      /* frames of windows */
      public JFrame CommandFrame = new JFrame("Commands");
      public JFrame ListFrame = new JFrame("Network List");
      public JFrame MessageFrame = new JFrame("Messages");
      
      public final JTextArea InMess = new JTextArea(10, 50);
      
      /* init calls the functions that create the windows.  It takes
	 the network as an arg because it must pass it to the other
	 windows, who all use it, and it takes the port the user is
	 using to listen for input.  init returns the text area to
	 which messages are printed. */

    public JTextArea init(Network net) {
		
	CreateMessageWindow(net);
	
	return InMess;
    }
    
    /* creates a window to ask what port the user wishes to use and
	 the person's username.  The default port is 4000.*/

      public void GetPortWindow(Network Net) {
	  final Network net = Net;
	  
	  final JLabel instructions = new JLabel("Choose your port and your username.");
	  JFrame frame = new JFrame();
	  JButton OKButton = new JButton("OK");
	  final JTextField portField = new JTextField(5);
	  final JTextField nameField = new JTextField(20);
	  JPanel textPane = new JPanel();

	  OKButton.setMnemonic(KeyEvent.VK_I);
	  OKButton.addActionListener(new ActionListener() {
		  public void actionPerformed(ActionEvent e) {
		      String tmp = portField.getText();
		      net.change_myPort(Integer.parseInt(tmp));
		      net.change_myUserName(nameField.getText());
		  }
	      });

	  final JLabel port = new JLabel("Port");
	  final JLabel name = new JLabel("Name");

	  textPane.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
	  textPane.setLayout(new BoxLayout(textPane, BoxLayout.Y_AXIS));
	  textPane.add(instructions);
	  textPane.add(port);
	  textPane.add(portField);
	  textPane.add(name);
	  textPane.add(nameField);
	  textPane.add(OKButton);
	  
	  frame.getContentPane().add(textPane);
	  frame.setVisible(true);
      }
      
      /* creates the window that receives messages and that the user
       * uses to send messages. */
      public void CreateMessageWindow(Network net) {
	  /* get the panels for the buttons that create command and network windows */
	  Component ComButtonPane = createComOpenButton(net);
	  
	  /* get the panel for the send messages button */
	  Component sendPanel = createSendButton(net);

	  /* incoming includes the text area where messages are received. */
	  Component inPanel = createIncoming();
	  
	  /* pack everything up */
	  MessageFrame.getContentPane().add(inPanel, BorderLayout.NORTH);
	  MessageFrame.getContentPane().add(ComButtonPane, BorderLayout.SOUTH);
	  MessageFrame.getContentPane().add(sendPanel, BorderLayout.CENTER);
	  MessageFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	  MessageFrame.pack();
	  /* display everything */
	  MessageFrame.setVisible(true);
	  
      }	
      
      /* CommandWindow contains buttons for available commands. */
      public void CreateCommandWindow(Network net) {

	  /* get buttons */
	  Component ExitButtonPane = createExitButton();
	  Component ConnectButtonPane = createConnectButton(net);
	  Component SettingsButtonPane = createSettingsButton(net);
	  
	  /* pack everthing up */
	  CommandFrame.getContentPane().add(Commands, BorderLayout.NORTH);
	  CommandFrame.getContentPane().add(ExitButtonPane, BorderLayout.EAST);
	  CommandFrame.getContentPane().add(SettingsButtonPane, BorderLayout.CENTER);
	  CommandFrame.getContentPane().add(ConnectButtonPane, BorderLayout.WEST);
	  CommandFrame.pack();
	  /* display everything */
	  CommandFrame.setVisible(true);
      }

    public Component createSettingsButton(Network Net) {
	final Network net = Net;
	    JButton SettingsButton = new JButton("Settings");
	    SettingsButton.setMnemonic(KeyEvent.VK_I);
	    
	    SettingsButton.addActionListener(new ActionListener() {
		    public void actionPerformed(ActionEvent e) {
			GetPortWindow(net);
		    }
	    });
	    
	    JPanel SettingsButtonPane = new JPanel();
	    SettingsButtonPane.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
	    SettingsButtonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
	    SettingsButtonPane.add(SettingsButton);
	    
	    return SettingsButtonPane;
    }
      
      /* make the network window.  The function gets a list of people
	 the user knows, and determines who is on and off the network.
	 The user can click on a person who is off the network to
	 attempt to connect to that person. */
      /* NOTE: this is not fully functional. */
      public void CreateNetworkWindow(Network net) {
	  Component ConnectButtonPane = createConnectButton(net);
	  
	  ListFrame.getContentPane().add(OnList, BorderLayout.NORTH);
	  ListFrame.getContentPane().add(ConnectButtonPane, BorderLayout.CENTER);
	  ListFrame.getContentPane().add(OffList, BorderLayout.SOUTH);
	  
	  ListFrame.pack();
	  ListFrame.setVisible(true);
      }
      
      /* makes a button that starts the In thread, which waits for people to connect. */
    
    /*      public Component createWaitButton(Network Net) {
	    final Network net = Net;
	    
	    JButton WaitButton = new JButton("Wait");
	    WaitButton.setMnemonic(KeyEvent.VK_I);
	    
	    WaitButton.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
	    In in = new In(net);
	    in.start();
	    }
	    });
	    
	    JPanel WaitButtonPane = new JPanel();
	    WaitButtonPane.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
	    WaitButtonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
	    WaitButtonPane.add(WaitButton);
	    
	    return WaitButtonPane;
	    }*/

      /* makes a button that launches a Connect window.  the user enters enters the address, the
	 port, and the other person's username.  The user then clicks the "go" button, and a new
	 Connection object is created, the connect function called, and the new connection added
	 to the network list (assuming the connection is made correctly. */
      public Component createConnectButton(Network Net) {
	  final Network net = Net;
	  JButton ConnectButton = new JButton("Connect");
	  ConnectButton.setMnemonic(KeyEvent.VK_I);
	  JPanel ConnectPane = new JPanel();

	  ConnectButton.addActionListener(new ActionListener() {
		  public void actionPerformed(ActionEvent e) {
		      /* create new window to ask about data */
		      JFrame ConnectFrame = new JFrame("Connect");
		      JPanel textPane = new JPanel();
		      final JTextField IP = new JTextField(17);
		      final JTextField PORT = new JTextField(5);
		      final JTextField NAME = new JTextField(20);
		
		      JButton GO = new JButton("Go!");
		      GO.setMnemonic(KeyEvent.VK_I);
		     
		      GO.addActionListener(new ActionListener() {
			      public void actionPerformed(ActionEvent e) {
				    
				  /* establish new connection */
				  Connection new_connect = new Connection(net);
				  /* data, data */
				  new_connect.assign_hostName(IP.getText());
				  String tmp = PORT.getText();
				  new_connect.assign_port(Integer.parseInt(tmp));
				  new_connect.assign_name(NAME.getText());
				  /* connect */
				  new_connect.connect();
				  /* add the new Connection to the network list */  
				  net.add(new_connect);
			      }
			  });
		     		
		      final JLabel IP_Address = new JLabel("IP address");
		      final JLabel Port = new JLabel("Port");
		      final JLabel Name = new JLabel("Name");

		      textPane.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
		      textPane.setLayout(new BoxLayout(textPane, BoxLayout.Y_AXIS));
		      textPane.add(IP_Address);
		      textPane.add(IP);
		      textPane.add(Port);
		      textPane.add(PORT);
		      textPane.add(Name);
		      textPane.add(NAME);
		      textPane.add(GO);
		 
		      //ConnectFrame.setBorderLayout(BorderFactory.createEmptyBorder(30,30,10,30));
		      ConnectFrame.getContentPane().add(textPane);
		      ConnectFrame.setVisible(true);
		  }
		 
	      });	
	  ConnectPane.setBorder(BorderFactory.createEmptyBorder(30,30,30,30));
	  ConnectPane.setLayout(new BoxLayout(ConnectPane, BoxLayout.Y_AXIS));
	  ConnectPane.add(ConnectButton);
	  return ConnectPane; 
      }

      /* creating a button to exit the program. */
      public Component createExitButton() {
	  JButton ExitButton = new JButton("Exit");
	  ExitButton.setMnemonic(KeyEvent.VK_I);
	   
	  ExitButton.addActionListener(new ActionListener() {
		  public void actionPerformed(ActionEvent e) {
		      System.exit(0);
		  }
	      });
	   
	  JPanel ExitButtonPane = new JPanel();
	  ExitButtonPane.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
	  ExitButtonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
	  ExitButtonPane.add(ExitButton);

	  return ExitButtonPane;
      }

      /* creates the panel the contains the text area that receives incoming messages. */
      public Component createIncoming() {
	  JPanel inPanel = new JPanel();
	  final JLabel IncomingMessage = new JLabel("Incoming messages");
	    
	  InMess.setLineWrap(true);
	  JScrollPane areaScrollPane = new JScrollPane(InMess);
	  areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
	  areaScrollPane.setPreferredSize(new Dimension(250, 250));
	  InMess.setEditable(false);

	  inPanel.add(IncomingMessage);
	  inPanel.add(InMess);
	    
	  return inPanel;
      }

      /* creates the panel that contains the text area and button that sends messages */
      public Component createSendButton(Network Net) {
	  final Network net = Net;
	  JPanel sendPanel = new JPanel();
	  JButton SendButton = new JButton("Send");
	  final JTextField OutMess = new JTextField(40);
	  SendButton.setMnemonic(KeyEvent.VK_I);

	  SendButton.addActionListener(new ActionListener() {
		  public void actionPerformed(ActionEvent e) {
		      /* here the code should send the appropriate people.*/
		      /* right now it's only going to display a message on screen.*/
		      String message = OutMess.getText();
				
		      /* for every peer in the network, */
		      int num_peers = net.get_numPeers();
		      for (int i = 0; i < num_peers; i++) {
			  net.get_Peer(i).Print_to_Socket(message);
		      }		
			
		      System.out.println(message);
		      InMess.append(message);
		  }
	      });
	
	  sendPanel.add(OutMess);
	  sendPanel.add(SendButton);

	  return sendPanel;
      }
   
      /* creates the command and network windows */
      public Component createComOpenButton(Network Net) {
	  final Network net = Net;
	  
	  JButton ComWinOpenButton = new JButton("Open Commands window");
	  ComWinOpenButton.setMnemonic(KeyEvent.VK_I);
	  JButton NetWinOpenButton = new JButton("Open Network window");
	  NetWinOpenButton.setMnemonic(KeyEvent.VK_I);
 
	  ComWinOpenButton.addActionListener(new ActionListener() {
		  public void actionPerformed(ActionEvent e) {
		      if (ComWinOpen == 0) {
			  CreateCommandWindow(net);
			  ComWinOpen = 1;
		      }
		  }
	      });
	 
	  NetWinOpenButton.addActionListener(new ActionListener() {
		  public void actionPerformed(ActionEvent e) {
		      if (NetWinOpen == 0) {
			  CreateNetworkWindow(net);
			  NetWinOpen = 1;
		      }
		  }
	      });

	  JPanel ComButtonPane = new JPanel();
	  ComButtonPane.setBorder(BorderFactory.createEmptyBorder(30,//top
								  30,//left
								  10,//bottom
								  30)//right
				  );
	  ComButtonPane.setLayout(new GridLayout(0, 1));
	  ComButtonPane.add(ComWinOpenButton);
	  ComButtonPane.add(NetWinOpenButton);

	  return ComButtonPane;					
      }
  };

