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

public class ChatClient extends JApplet implements ActionListener, KeyListener, Runnable
{
	boolean connected = false;
	Socket clientSocket = null;
	BufferedReader br = null;
	PrintWriter pw = null;
	Thread runner = null;

	//.
	static int width = 550;
	static int height = 300;
	Container pane = null;
	Border myBorder = BorderFactory.createEtchedBorder();

	JPanel connectPanel = new JPanel();
	JLabel text1 = new JLabel("Host/IP:", JLabel.LEFT);
	JTextField ip = new JTextField("127.0.0.1", 10);
	JLabel text2 = new JLabel("Port:", JLabel.LEFT);
	JTextField port = new JTextField("5000", 6);
	JLabel text3 = new JLabel("Name:", JLabel.LEFT);
	JTextField name = new JTextField("arkibald", 10);
	JButton connect = new JButton("Connect   ");

	JPanel chatBoardPanel = new JPanel();
	JTextArea chatBoard = new JTextArea();

	JPanel buttomPanel = new JPanel();
	JTextField chatLine = new JTextField();
	JComboBox userSelect = new JComboBox();
	JButton updateUserList = new JButton("");

	public void init()
	{
	  setUpWindow();
	}
	void setUpWindow()
	{
	  setSize(width, height);
	  pane = getContentPane();
	  pane.setLayout(new BorderLayout());

	  //making connect panel.
	  connectPanel.setBorder(myBorder);
	  pane.add(connectPanel, BorderLayout.NORTH);

	  connectPanel.add(text1);
	  connectPanel.add(ip);
	  connectPanel.add(text2);
	  connectPanel.add(port);
	  connectPanel.add(text3);
	  connectPanel.add(name);
	  connectPanel.add(connect);
	  connect.addActionListener(this);

	  //making chatBoard.
	  chatBoardPanel.setBorder(myBorder);
	  chatBoardPanel.setLayout(new BorderLayout());
	  pane.add(chatBoardPanel, BorderLayout.CENTER);
	  chatBoardPanel.add(new JScrollPane((Component)chatBoard), BorderLayout.CENTER);

	  //making chatLine
	  buttomPanel.setBorder(myBorder);
	  buttomPanel.setLayout(new BorderLayout());
	  pane.add(buttomPanel, BorderLayout.SOUTH);
	  buttomPanel.add(chatLine, BorderLayout.CENTER);
	  chatLine.addKeyListener(this);

	  JPanel junk = new JPanel();
	  buttomPanel.add(junk, BorderLayout.EAST);
	  junk.setLayout(new BorderLayout());

	  userSelect.addItem("all");
	  junk.add(userSelect, BorderLayout.CENTER);
	  updateUserList.setBackground(Color.blue);
	  junk.add(updateUserList, BorderLayout.EAST);
	  updateUserList.addActionListener(this);

	  chatBoard.append("*Welcome to ChatClient made by Mads Lenskjær 1-4-2001 (using java 1.3)\n");
	}
	//

	public void start() {}
	public void stop()
	{
	  cleanUp();
	}
	public void actionPerformed(ActionEvent evt)
	{
	  Object s = evt.getSource();
	  if(s instanceof JButton)
	  {
	    JButton b = (JButton)s;
	    if(b == connect)
	    {
	      connected = !connected;
	      if(connected)
	      {
	        try
	        { int myPort = Integer.parseInt(port.getText());
	          clientSocket = new Socket(ip.getText(), myPort);

	          br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
	          pw = new PrintWriter(clientSocket.getOutputStream(), true);
	          pw.println(name.getText());
	          connect.setText("Disconnect");
	          runner = new Thread(this);
	          runner.start();
	          chatBoard.append("*Connection established with server.\n*Please wait while the server evaluate your name, and announce you in the chatroom\n");
	        }catch(Exception e)
	        {
	          connected = false;
	          connect.setText("Connect   ");
	          chatBoard.append("*Couldent open connection to server\n");
	          return ;
	        }
	      }
	      else
	      { cleanUp();
	      }
	    }
	    else if(b == updateUserList && connected)
	    {
	      pw.println("/UserList ");
	    }
	  }
	}
	void cleanUp()
	{
	  try
	  {
        if(runner != null)
          runner.interrupt();
        runner = null;
        if(clientSocket != null)
          clientSocket.close();
        clientSocket = null;
	    connect.setText("Connect   ");
	    if(connected)
	    { connected = false;
	      chatBoard.append("*Connection to server has been closed\n");
	    }
	  }catch(IOException e) {}

	}
	public void keyTyped(java.awt.event.KeyEvent evt) { }
	public void keyReleased(java.awt.event.KeyEvent evt) {}
	public void keyPressed(java.awt.event.KeyEvent evt)
	{
      char code = evt.getKeyChar();
	  if(code == '\n')
	  {
	    if(connected)
	    { String l = chatLine.getText();
	      l = l.trim();
	      char operator = l.charAt(0);
	      if(operator != '/')
	      {
	        String to = (String)userSelect.getSelectedItem();
	        if(to.equals("all"))
	          pw.println("/cast all " +  name.getText() + ": " + l);
	        else
	          pw.println("/cast " + to + " " + name.getText() + ": " + l);
	      }
	    }
	    chatLine.setText("");
	  }
	}

	//Reciever thread.
	public void run()
	{
	  try
	  {
	    String l="";
	    while(runner != null && !runner.interrupted() && l != null)
	    { if((l = br.readLine()) != null)
	      {
	        l = l.trim();
	        if(l.charAt(0) == '/')
	        {
	          StringTokenizer token = new StringTokenizer(l, " ");
	          String commando = token.nextToken();

	          //Message broadcasted to all.
	          if(commando.equals("/cast"))
	          {
	            String msg = token.nextToken("\0");
	            msg = msg.trim();
	            chatBoard.append("(broadcast) "+msg +"\n");
	          }
	          //Personal message for the client.
	          else if(commando.equals("/personal"))
	          {
	            String msg = token.nextToken("\0");
	            msg = msg.trim();
	            chatBoard.append("(personal) " + msg +"\n");
	          }
	          //A new userlist has arrived.
	          else if(commando.equals("/UserList"))
	          {
	            String newUser = "";
	            userSelect.removeAllItems();
	            userSelect.addItem("all");
	            while(token.hasMoreElements())
	            {
	              newUser = token.nextToken(" \0");
	              newUser = newUser.trim();
	              userSelect.addItem(newUser);
	            }
	          }
	          //The clients name wasent unique.
              else if(commando.equals("/ChangeName"))
	          {
	            chatBoard.append("*Your handle was not unique. The server has changed it!\n");
	            String newName = token.nextToken("\0");
	            newName = newName.trim();
	            name.setText(newName);
	          }
	          //A new user has joined.
	          else if(commando.equals("/NewUser"))
	          {
	            String newName = token.nextToken(" \0");
	            chatBoard.append("*A new user has joined the chatroom called " + newName+"\n");
	          }
	          //A user has disconnected from the chat.
	          else if(commando.equals("/QuitUser"))
	          {
	            String newName = token.nextToken(" \0");
	            chatBoard.append("*" + newName + " has left the chatroom."+"\n");
	          }
	        }
	      }
	    }
	    if(connected)
	    {
	      connected = !connected;
	      connect.setText("Connect   ");
	      chatBoard.append("*Lost connection to server\n");
	      clientSocket.close();
	    }
      }catch(IOException e) {}
	}
}