//oef 12
//0: disconnect
//1: addname
//9: normal text
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

public class Client extends JFrame implements ActionListener {
   private Container cont;
   private GridBagLayout layout;
   private GridBagConstraints layoutC;
   private JTextField enter;
   private JTextArea display;
   private JList users;
   private JMenuItem Mconnect;
   private JMenuItem Disconnect;
   private JMenuBar menubar;
   private JMenu connect;
   private JMenuItem exitMenu;
   private JLabel condiscon;

   private DatagramPacket sendPacket, receivePacket;
   private DatagramSocket socket,hulpsocket;
   private boolean verbonden=false;
   private InetAddress MyAddress;

   private Vector UserVector=new Vector();
   private String UserName="";

   public Client()
   {
      super( "Client" );
      setResizable(false);

// ip adres op te zoeken door msdos bevel 'ipconfig'
// moet ip adres zijn van pc waar Server op draait
      try{MyAddress=InetAddress.getByName("10.2.9.104");}
      catch(UnknownHostException u){};

      //adding yourself to UserVector
      while (UserName.equals("")){
	 UserName=JOptionPane.showInputDialog("Please enter your name");
      }

      //create menu
      menubar=new JMenuBar();
      setJMenuBar(menubar);
      JMenu connect=new JMenu("Connect");
      connect.setMnemonic('C');
      Mconnect=new JMenuItem("Connect");
      Mconnect.setEnabled(true);
      Mconnect.setMnemonic('o');
      Mconnect.addActionListener(new ActionListener(){
	 public void actionPerformed(ActionEvent e){
	       verbonden=true;
	       Mconnect.setEnabled(false);
	       Disconnect.setEnabled(true);
	       condiscon.setText("Connected");
	       sendUserName();
	 }
      });
      connect.add(Mconnect);
      Disconnect=new JMenuItem("Disconnect");
      Disconnect.setEnabled(false);
      Disconnect.setMnemonic('D');
      Disconnect.addActionListener(new ActionListener(){
	 public void actionPerformed(ActionEvent e){
	    if (verbonden) sendQuit();
	    verbonden=false;
	    Mconnect.setEnabled(true);
	    Disconnect.setEnabled(false);
            condiscon.setText("Disconnected");
	 }
      });
      connect.add(Disconnect);
      connect.addSeparator();
      exitMenu=new JMenuItem("Exit");
      exitMenu.setMnemonic('E');
      exitMenu.addActionListener(new ActionListener(){
	 public void actionPerformed(ActionEvent e){
	    sendQuit();
	    System.exit(0);
	 }
      });
      connect.add(exitMenu);
      menubar.add(connect);

      //create frame
      layout=new GridBagLayout();
      cont=getContentPane();
      cont.setLayout(layout);
      layoutC=new GridBagConstraints();

      //input area
      enter = new JTextField( "Type message here" );
      enter.addActionListener( this );
      enter.addActionListener(new ActionListener(){
	 public void actionPerformed(ActionEvent e){
	    enter.setText("");
	 }
      });
      layoutC.fill=GridBagConstraints.HORIZONTAL;
      addComponent(enter,0,1,1,1); 

      //output area
      display = new JTextArea(10,40);
      display.setLineWrap(true);
      display.setEditable(false);
      layoutC.fill=GridBagConstraints.BOTH;
      addComponent( new JScrollPane(display),0,0,1,1); 

      //user list
      users=new JList(UserVector);
      users.setFixedCellWidth(90);
      layoutC.fill=GridBagConstraints.VERTICAL;
      addComponent(new JScrollPane(users),1,0,1,2);

      //status
      condiscon=new JLabel("Disconnected");
      layoutC.fill=GridBagConstraints.NONE;
      addComponent(condiscon,0,2,2,1);

      setSize( 600, 290 );
      show();

      try {
         socket = new DatagramSocket();
      }
      catch( SocketException se ) {
         se.printStackTrace();
         System.exit( 1 );
      }
   }

   private void sendUserName(){
      String s='1'+UserName;
      byte data[] = s.getBytes();
      try{
         sendPacket = new DatagramPacket( data, data.length,
            MyAddress, 5000 );
         socket.send( sendPacket );
      }
      catch(IOException exception ) { 
         display.append( exception.toString() + "\n" ); 
         exception.printStackTrace(); 
      }
   }

   private void sendQuit(){

      String s='0'+UserName;
      byte data[] = s.getBytes();
      try{
         sendPacket = new DatagramPacket( data, data.length,
            MyAddress, 5000 );
         socket.send( sendPacket );
      }
      catch(IOException exception ) { 
         display.append( exception.toString() + "\n" ); 
         exception.printStackTrace(); 
      }
      UserVector.clear();
      users.updateUI();
   }

   private void addComponent(Component c,int xvalue,int yvalue,int width,int
height){
      layoutC.gridx=xvalue;
      layoutC.gridy=yvalue;
      layoutC.gridwidth=width;
      layoutC.gridheight=height;
      layout.setConstraints(c,layoutC);
      cont.add(c);
   }

   public void waitForPackets()
   {
      while ( true ) {
         try {
            // set up packet
            byte data[] = new byte[ 100 ];
            receivePacket =
               new DatagramPacket( data, data.length );

            // wait for packet
            socket.receive( receivePacket );

	    //search for code
	    String input=new String( receivePacket.getData(), 0, 
               receivePacket.getLength() );
	    int code=(int)input.charAt(0)-(int)('0');
	    String realInput=new String(input.substring(1));
 
            // process packet
	    switch(code){
	       case 0: removeUser(realInput);
	       break;
	       case 1:UserVector.addElement(realInput);
		  users.updateUI();
	       break;
	       case 9:
		  display.append("\n"+realInput);
		  display.setCaretPosition(
		  display.getText().length() );
	       break;
	    }
         }
         catch( IOException exception ) {
            display.append( exception.toString() + "\n" );
            exception.printStackTrace();
         }
      }
   }

   private void removeUser(String name){
      int i=0;
      while (i<UserVector.size() && !name.equals(UserVector.get(i)))i++;
      UserVector.remove(i);
      users.updateUI();
   }

   public void actionPerformed( ActionEvent e ){
      if (verbonden){
	 try {
	    String s = '9'+UserName+": "+e.getActionCommand();
	    byte data[] = s.getBytes();
	    sendPacket = new DatagramPacket( data, data.length,
	    MyAddress, 5000 );
	    socket.send( sendPacket );
	 }
	 catch ( IOException exception ) {
	    System.out.println(exception.toString());
	 }
      };
   }

   public static void main( String args[] )
   {
      Client app = new Client();

      app.addWindowListener(
         new WindowAdapter() {
            public void windowClosing( WindowEvent e )
            {
               System.exit( 0 );
            }
         }
      );

      app.waitForPackets();
   }
}
