package it.gotoandplay.smartfoxclient.examples.SmartFoxJChat;

import it.gotoandplay.smartfoxclient.ISFSEventListener;
import it.gotoandplay.smartfoxclient.SFSEvent;
import it.gotoandplay.smartfoxclient.SmartFoxClient;
import it.gotoandplay.smartfoxclient.data.Room;
import it.gotoandplay.smartfoxclient.data.User;
import it.gotoandplay.smartfoxclient.util.Entities;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.UIManager;

/**
 * The main frame for the Matrix program
 * 
 * @author brpocock
 * 
 */
public class MainFrame extends javax.swing.JFrame implements
		ISFSEventListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = 7966244233930185613L;

	public static void main (final String args[]) {
		final SmartFoxClient s = new SmartFoxClient (true);
		java.awt.EventQueue.invokeLater (new Runnable () {
			public void run () {
				new MainFrame ().setVisible (true);
			}
		});
	}

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JButton buttonAlertOk;
	private javax.swing.JButton buttonCreateRoomCancel;
	private javax.swing.JButton buttonCreateRoomOk;

	private javax.swing.JButton buttonJoin;

	private javax.swing.JButton buttonJoinPrivateCancel;

	private javax.swing.JButton buttonJoinPrivateOk;

	private javax.swing.JButton buttonLogin;

	private javax.swing.JButton buttonLogout;

	private javax.swing.JButton buttonNewRoom;

	private javax.swing.JButton buttonSend;

	private javax.swing.JButton buttonSendPrivate;

	private javax.swing.JButton buttonSendPrivateCancel;

	private javax.swing.JButton buttonSendPrivateOk;

	/**
 * 
 */
	private StringBuilder chatHistory;

	private javax.swing.JDialog dialogAlert;

	private javax.swing.JDialog dialogJoinPrivateRoom;

	private javax.swing.JDialog dialogLogin;

	private javax.swing.JDialog dialogNewRoom;

	private javax.swing.JDialog dialogPrivate;

	private javax.swing.JLabel labelAlert;

	private javax.swing.JLabel labelChatHistory;

	private javax.swing.JLabel labelCopyright;

	private javax.swing.JLabel labelMaxUsers;

	private javax.swing.JLabel labelPassword;
	private javax.swing.JLabel labelPrivateMessage;
	private javax.swing.JLabel labelPrivateRoomPassword;
	private javax.swing.JLabel labelRoomList;
	private javax.swing.JLabel labelRoomName;
	private javax.swing.JLabel labelUserList;
	private javax.swing.JLabel labelUserName;
	private javax.swing.JList listRooms;
	private javax.swing.JList listUsers;
	/**
     * 
     */
	private final RoomListModel roomListModel;
	private javax.swing.JScrollPane scrollPaneChatHistory;
	private javax.swing.JScrollPane scrollPaneRoomList;
	private javax.swing.JScrollPane scrollPaneUserList;
	/**
	 * 
	 */
	private final SmartFoxClient sfs;
	private javax.swing.JSlider sliderNewRoomMaxUsers;
	private javax.swing.JTextPane textChatHistory;
	private javax.swing.JTextField textChatMessage;
	private javax.swing.JPasswordField textJoinPrivatePassword;
	private javax.swing.JTextField textNewRoomName;
	private javax.swing.JPasswordField textNewRoomPassword;
	private javax.swing.JTextField textPrivateMessage;
	private javax.swing.JTextField textUserName;
	// End of variables declaration//GEN-END:variables
	/**
     * 
     */
	private final UserListModel userListModel;

	/** Creates new form MainFrame */
	public MainFrame () {
		// Sets the native look and feel
		try {
			UIManager.setLookAndFeel (UIManager
					.getCrossPlatformLookAndFeelClassName ());
			// UIManager.getSystemLookAndFeelClassName());
		} catch (final Exception ex) {
			ex.printStackTrace ();
		}

		initComponents ();
		final URL iconURL = this.getClass ().getClassLoader ()
				.getResource ("resources/redFox.gif");
		if (iconURL != null) {
			final ImageIcon icon = new ImageIcon (iconURL);
			setIconImage (icon.getImage ());
		}

		// Creates new instance of SmatFoxClient and adds the event
		// handlers
		sfs = new SmartFoxClient (true);
		getSfs ().addEventListener (SFSEvent.onConfigLoadSuccess, this);
		getSfs ().addEventListener (SFSEvent.onConfigLoadFailure, this);
		getSfs ().addEventListener (SFSEvent.onConnection, this);
		getSfs ().addEventListener (SFSEvent.onConnectionLost, this);
		getSfs ().addEventListener (SFSEvent.onLogin, this);
		getSfs ().addEventListener (SFSEvent.onRoomListUpdate, this);
		getSfs ().addEventListener (SFSEvent.onRoomAdded, this);
		getSfs ().addEventListener (SFSEvent.onCreateRoomError, this);
		getSfs ().addEventListener (SFSEvent.onRoomDeleted, this);
		getSfs ().addEventListener (SFSEvent.onUserCountChange, this);
		getSfs ().addEventListener (SFSEvent.onJoinRoom, this);
		getSfs ().addEventListener (SFSEvent.onJoinRoomError, this);
		getSfs ().addEventListener (SFSEvent.onUserEnterRoom, this);
		getSfs ().addEventListener (SFSEvent.onUserLeaveRoom, this);
		getSfs ().addEventListener (SFSEvent.onPublicMessage, this);
		getSfs ().addEventListener (SFSEvent.onPrivateMessage, this);

		// Sets the Room and User list models to the user and room lists
		roomListModel = (RoomListModel) getListRooms ().getModel ();
		userListModel = (UserListModel) listUsers.getModel ();

		// Loads the config file.
		getSfs ().loadConfig ("config.xml", false);
	}

	/**
	 * Closes the dialog box with the error messages.
	 * 
	 * @param evt WRITEME
	 */
	private void buttonAlertOkActionPerformed (
			final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonAlertOkActionPerformed
		getDialogAlert ().dispose ();
	}// GEN-LAST:event_buttonAlertOkActionPerformed

	/**
	 * Closes the new room dialog box.
	 * 
	 * @param evt WRITEME
	 */
	private void buttonCreateRoomCancelActionPerformed (
			final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonCreateRoomCancelActionPerformed
		dialogNewRoom.dispose ();
	}// GEN-LAST:event_buttonCreateRoomCancelActionPerformed

	/**
	 * Creates new room
	 * 
	 * @param evt WRITEME
	 */
	private void buttonCreateRoomOkActionPerformed (
			final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonCreateRoomOkActionPerformed
		final String roomName = textNewRoomName.getText ();
		if (roomName.length () > 0) {
			dialogNewRoom.dispose ();
			// Gets the new room properties for the user input
			// and sends them to the server.
			final int maxUsers = sliderNewRoomMaxUsers.getValue ();
			final String password = new String (textNewRoomPassword
					.getPassword ());
			final Map <String, Object> roomProperties = new HashMap <String, Object> ();
			roomProperties.put ("password", password);
			getSfs ().createRoom (roomName, maxUsers, roomProperties);
		}
	}// GEN-LAST:event_buttonCreateRoomOkActionPerformed

	/**
	 * Joins the user to the selected room. If the room is private a
	 * dilog box that asks for the password is shown.
	 * 
	 * @param evt
	 */
	private void buttonJoinActionPerformed (
			final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonJoinActionPerformed
		final Room room = (Room) getListRooms ().getSelectedValue ();
		if (room.isPrivate ()) {
			dialogJoinPrivateRoom.pack ();
			dialogJoinPrivateRoom.setLocation (getX () + 100,
					getY () + 100);
			textJoinPrivatePassword.setText ("");
			dialogJoinPrivateRoom.setVisible (true);
		} else {
			getSfs ().joinRoom (room.getId ());
		}
	}// GEN-LAST:event_buttonJoinActionPerformed

	/**
	 * Closes the dialog box that allows the user to join to private
	 * room
	 * 
	 * @param evt
	 */
	private void buttonJoinPrivateCancelActionPerformed (
			final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonJoinPrivateCancelActionPerformed
		dialogJoinPrivateRoom.dispose ();
	}// GEN-LAST:event_buttonJoinPrivateCancelActionPerformed

	/**
	 * Joins the user to private room
	 * 
	 * @param evt
	 */
	private void buttonJoinPrivateOkActionPerformed (
			final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonJoinPrivateOkActionPerformed
		if (textJoinPrivatePassword.getPassword ().length > 0) {
			dialogJoinPrivateRoom.dispose ();
			// Gets the room password
			final String password = new String (textJoinPrivatePassword
					.getPassword ());
			// Joins the user to the currently selected room
			final Room room = (Room) getListRooms ()
					.getSelectedValue ();
			getSfs ().joinRoom (room.getId (), password, false);
		}
	}// GEN-LAST:event_buttonJoinPrivateOkActionPerformed

	/**
	 * Logs the user in.
	 * 
	 * @param evt
	 */
	private void buttonLoginActionPerformed (
			final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonLoginActionPerformed
		if (getTextUserName ().getText ().length () > 0) {
			getDialogLogin ().dispose ();
			getSfs ().login (getSfs ().defaultZone,
					getTextUserName ().getText (), "");
		}
	}// GEN-LAST:event_buttonLoginActionPerformed

	/**
	 * Disconnects the user.
	 * 
	 * @param evt
	 */
	private void buttonLogoutActionPerformed (
			final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonLogoutActionPerformed
		getSfs ().disconnect ();
	}// GEN-LAST:event_buttonLogoutActionPerformed

	/**
	 * Closes the private message dialog box.
	 * 
	 * @param evt
	 */
	private void cancelSendingWhisper (
			final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonSendPrivateCancelActionPerformed
		dialogPrivate.dispose ();
	}// GEN-LAST:event_buttonSendPrivateCancelActionPerformed

	/**
	 * @return the buttonAlertOk
	 */
	public javax.swing.JButton getButtonAlertOk () {
		return buttonAlertOk;
	}

	/**
	 * @return the buttonJoin
	 */
	public javax.swing.JButton getButtonJoin () {
		return buttonJoin;
	}

	/**
	 * @return the buttonLogout
	 */
	public javax.swing.JButton getButtonLogout () {
		return buttonLogout;
	}

	/**
	 * @return the buttonNewRoom
	 */
	public javax.swing.JButton getButtonNewRoom () {
		return buttonNewRoom;
	}

	/**
	 * @return the buttonSend
	 */
	public javax.swing.JButton getButtonSend () {
		return buttonSend;
	}

	/**
	 * @return the buttonSendPrivate
	 */
	public javax.swing.JButton getButtonSendPrivate () {
		return buttonSendPrivate;
	}

	/**
	 * @return the chatHistory
	 */
	public StringBuilder getChatHistory () {
		return chatHistory;
	}

	/**
	 * @return the dialogAlert
	 */
	public javax.swing.JDialog getDialogAlert () {
		return dialogAlert;
	}

	/**
	 * @return the dialogLogin
	 */
	public javax.swing.JDialog getDialogLogin () {
		return dialogLogin;
	}

	/**
	 * @return the labelAlert
	 */
	public javax.swing.JLabel getLabelAlert () {
		return labelAlert;
	}

	/**
	 * @return the listRooms
	 */
	public javax.swing.JList getListRooms () {
		return listRooms;
	}

	/**
	 * @return the roomListModel
	 */
	public RoomListModel getRoomListModel () {
		return roomListModel;
	}

	/**
	 * @return the sfs
	 */
	public SmartFoxClient getSfs () {
		return sfs;
	}

	/**
	 * @return the textChatHistory
	 */
	public javax.swing.JTextPane getTextChatHistory () {
		return textChatHistory;
	}

	/**
	 * @return the textChatMessage
	 */
	public javax.swing.JTextField getTextChatMessage () {
		return textChatMessage;
	}

	/**
	 * @return the textUserName
	 */
	public javax.swing.JTextField getTextUserName () {
		return textUserName;
	}

	/**
	 * @return the userListModel
	 */
	public UserListModel getUserListModel () {
		return userListModel;
	}

	/**
	 * Handles the SFS related events
	 * 
	 * @param event
	 */
	public void handleEvent (final SFSEvent event) {
		// Swing is not thread safety so this code is excuted at the
		// event dispatch thread
		java.awt.EventQueue.invokeLater (new Runnable () {
			public void run () {
				// if the config file is loaded then it connects to the
				// SFS
				if (event.getName ().equals (
						SFSEvent.onConfigLoadSuccess)) {
					MainFrame.this.getSfs ().connect (
							MainFrame.this.getSfs ().ipAddress,
							MainFrame.this.getSfs ().port);
				}
				// if the config file fails to load an error is shown
				else if (event.getName ().equals (
						SFSEvent.onConfigLoadFailure)) {
					MainFrame.this.getLabelAlert ().setText (
							"Failed loading config file.");
					MainFrame.this.getDialogAlert ().pack ();
					MainFrame.this.getDialogAlert ().setLocation (
							MainFrame.this.getX () + 100,
							MainFrame.this.getY () + 100);
					MainFrame.this.getDialogAlert ().setVisible (true);
				} else if (event.getName ().equals (
						SFSEvent.onConnection)) {
					// if the connections is successful login dialog is
					// shown
					if (event.getParams ().getBool ("success")) {
						MainFrame.this.getDialogLogin ().pack ();
						MainFrame.this.getTextUserName ().setText ("");
						MainFrame.this.getDialogLogin ().setLocation (
								MainFrame.this.getX () + 100,
								MainFrame.this.getY () + 100);
						MainFrame.this.getDialogLogin ().setVisible (
								true);
						MainFrame.this.getButtonLogout ().setEnabled (
								true);
					}
					// otherwise error message is shown
					else {
						MainFrame.this
								.getLabelAlert ()
								.setText (
										"Failed connecting to "
												+ MainFrame.this
														.getSfs ().ipAddress
												+ ":"
												+ MainFrame.this
														.getSfs ().port);
						MainFrame.this.getDialogAlert ().pack ();
						MainFrame.this.getDialogAlert ().setLocation (
								MainFrame.this.getX () + 100,
								MainFrame.this.getY () + 100);
						MainFrame.this.getDialogAlert ().setVisible (
								true);
					}
				}
				// When the connection is lost
				// (including when the user is disconnect when he/she
				// press logout)
				// the UI is dissabled and message is shown
				else if (event.getName ().equals (
						SFSEvent.onConnectionLost)) {
					MainFrame.this.getButtonJoin ().setEnabled (false);
					MainFrame.this.getButtonNewRoom ().setEnabled (
							false);
					MainFrame.this.getButtonSendPrivate ().setEnabled (
							false);
					MainFrame.this.getButtonLogout ()
							.setEnabled (false);
					MainFrame.this.getTextChatMessage ().setEnabled (
							false);
					MainFrame.this.getButtonSend ().setEnabled (false);
					MainFrame.this.getLabelAlert ().setText (
							"Connection was lost");
					MainFrame.this.getDialogAlert ().pack ();
					MainFrame.this.getDialogAlert ().setLocation (
							MainFrame.this.getX () + 100,
							MainFrame.this.getY () + 100);
					MainFrame.this.getDialogAlert ().setVisible (true);
				} else if (event.getName ().equals (SFSEvent.onLogin)) {
					if (event.getParams ().getBool ("success")) {
						// clers the chat history
						MainFrame.this
								.setChatHistory (new StringBuilder ());
						MainFrame.this.getTextChatHistory ().setText (
								"");
					}
					// if the login is not successful then error message
					// and
					// the login dialog are shown intil it's successful
					else {
						final String error = event.getParams ()
								.getString ("error");
						MainFrame.this.getLabelAlert ().setText (error);
						MainFrame.this.getDialogAlert ().pack ();
						MainFrame.this.getDialogAlert ().setLocation (
								MainFrame.this.getX () + 100,
								MainFrame.this.getY () + 100);
						MainFrame.this.getButtonAlertOk ()
								.addActionListener (
										new ActionListener () {
											public void actionPerformed (
													final ActionEvent e) {
												MainFrame.this
														.getDialogAlert ()
														.dispose ();
												MainFrame.this
														.getButtonAlertOk ()
														.removeActionListener (
																this);
												MainFrame.this
														.getDialogLogin ()
														.pack ();
												MainFrame.this
														.getDialogLogin ()
														.setLocation (
																MainFrame.this
																		.getX () + 100,
																MainFrame.this
																		.getY () + 100);
												MainFrame.this
														.getTextUserName ()
														.setText ("");
												MainFrame.this
														.getDialogLogin ()
														.setVisible (
																true);
											}
										});
						MainFrame.this.getDialogAlert ().setVisible (
								true);
					}
				}
				// When the room list is received the room list is
				// updated and
				// the user is joined to the default room
				else if (event.getName ().equals (
						SFSEvent.onRoomListUpdate)) {
					MainFrame.this.getSfs ().autoJoin ();
					final Map <Integer, Room> roomListMap = (Map <Integer, Room>) event
							.getParams ().get ("roomList");
					final Map <Integer, Room> roomList = roomListMap;
					MainFrame.this.getRoomListModel ().setRoomList (
							roomList);
				}
				// When new room is created it's added to the room list.
				else if (event.getName ().equals (SFSEvent.onRoomAdded)) {
					final Room room = (Room) event.getParams ().get (
							"room");
					MainFrame.this.getRoomListModel ().addRoom (room);

				}
				// If room creation failed an error message is shown
				else if (event.getName ().equals (
						SFSEvent.onCreateRoomError)) {
					final String error = "Room creation error: "
							+ event.getParams ().getString ("error");
					MainFrame.this.getLabelAlert ().setText (error);
					MainFrame.this.getDialogAlert ().pack ();
					MainFrame.this.getDialogAlert ().setLocation (
							MainFrame.this.getX () + 100,
							MainFrame.this.getY () + 100);
					MainFrame.this.getDialogAlert ().setVisible (true);
				}
				// When a room is deleted it's removed from the room
				// list.
				else if (event.getName ().equals (
						SFSEvent.onRoomDeleted)) {
					final Room room = (Room) event.getParams ().get (
							"room");
					MainFrame.this.getRoomListModel ()
							.removeRoom (room);
				}
				// When the user count change the room list is refreshed
				else if (event.getName ().equals (
						SFSEvent.onUserCountChange)) {
					final Room room = (Room) event.getParams ().get (
							"room");
					MainFrame.this.getRoomListModel ()
							.updateRoom (room);
				}
				// When the user joins new room then a message is added
				// to
				// the chat history and the UI is enable
				else if (event.getName ().equals (SFSEvent.onJoinRoom)) {
					final Room room = (Room) event.getParams ().get (
							"room");
					MainFrame.this.getListRooms ().setSelectedValue (
							room, true);
					MainFrame.this.getButtonJoin ().setEnabled (false);
					MainFrame.this.getTextChatMessage ().setEnabled (
							true);
					MainFrame.this.getButtonSend ().setEnabled (true);
					MainFrame.this.getButtonNewRoom ()
							.setEnabled (true);
					MainFrame.this.getUserListModel ().setUserList (
							room.getUserList ());
					MainFrame.this.getChatHistory ().append (
							"<font color='#cc0000'>{ Room <b>");
					MainFrame.this.getChatHistory ().append (
							room.getName ());
					MainFrame.this.getChatHistory ().append (
							"</b> joined }</font><br>");
					MainFrame.this.getTextChatHistory ().setText (
							MainFrame.this.getChatHistory ()
									.toString ());
					MainFrame.this.getTextChatMessage ()
							.requestFocus ();
				}
				// When the user fails to joins new room then
				// an error message is shown
				else if (event.getName ().equals (
						SFSEvent.onJoinRoomError)) {
					final String error = "Room join error: "
							+ event.getParams ().getString ("error");
					MainFrame.this.getLabelAlert ().setText (error);
					MainFrame.this.getDialogAlert ().pack ();
					MainFrame.this.getDialogAlert ().setLocation (
							MainFrame.this.getX () + 100,
							MainFrame.this.getY () + 100);
					MainFrame.this.getDialogAlert ().setVisible (true);
				}
				// When a user enter the room the user list is updated
				else if (event.getName ().equals (
						SFSEvent.onUserEnterRoom)) {
					final User user = (User) event.getParams ().get (
							"user");
					MainFrame.this.getUserListModel ().addUser (user);

				}
				// When a user leave the room the user list is updated
				else if (event.getName ().equals (
						SFSEvent.onUserLeaveRoom)) {
					final int userId = (Integer) event.getParams ()
							.get ("userId");
					MainFrame.this.getUserListModel ().removeUser (
							userId);
				}
				// When public message is received it's added to the
				// chat history
				else if (event.getName ().equals (
						SFSEvent.onPublicMessage)) {
					final User sender = (User) event.getParams ().get (
							"sender");
					String msg = event.getParams ().getString (
							"message");
					// Escapes the HTML tags
					msg = Entities.encodeEntities (msg);
					msg = MessageProcessor.parseSmiles (msg);
					MainFrame.this.getChatHistory ().append ("<b>[");
					MainFrame.this.getChatHistory ().append (
							sender.getName ());
					MainFrame.this.getChatHistory ().append ("]:</b> ");
					MainFrame.this.getChatHistory ().append (msg);
					MainFrame.this.getChatHistory ().append ("<br>");

					MainFrame.this.getTextChatHistory ().setText (
							MainFrame.this.getChatHistory ()
									.toString ());
				}
				// When private message is received it's added to the
				// chat history
				else if (event.getName ().equals (
						SFSEvent.onPrivateMessage)) {
					final User sender = (User) event.getParams ().get (
							"sender");
					String msg = event.getParams ().getString (
							"message");
					// Escapes the HTML tags
					msg = Entities.encodeEntities (msg);
					msg = MessageProcessor.parseSmiles (msg);
					MainFrame.this.getChatHistory ().append (
							"<b><font color='#550000'>[PM - ");
					MainFrame.this.getChatHistory ().append (
							sender.getName ());
					MainFrame.this.getChatHistory ().append ("]:</b> ");
					MainFrame.this.getChatHistory ().append (msg);
					MainFrame.this.getChatHistory ().append ("<br>");

					MainFrame.this.getTextChatHistory ().setText (
							MainFrame.this.getChatHistory ()
									.toString ());
				}
			}
		});
	}

	/**
	 * This method is called from within the constructor to initialize
	 * the form. WARNING: Do NOT modify this code. The content of this
	 * method is always regenerated by the Form Editor.
	 */
	@SuppressWarnings ("unchecked")
	// <editor-fold defaultstate="collapsed"
	// desc="Generated Code">//GEN-BEGIN:initComponents
	private void initComponents () {

		dialogNewRoom = new javax.swing.JDialog ();
		labelRoomName = new javax.swing.JLabel ();
		textNewRoomName = new javax.swing.JTextField ();
		labelMaxUsers = new javax.swing.JLabel ();
		labelPassword = new javax.swing.JLabel ();
		textNewRoomPassword = new javax.swing.JPasswordField ();
		buttonCreateRoomOk = new javax.swing.JButton ();
		buttonCreateRoomCancel = new javax.swing.JButton ();
		sliderNewRoomMaxUsers = new javax.swing.JSlider ();
		dialogPrivate = new javax.swing.JDialog ();
		labelPrivateMessage = new javax.swing.JLabel ();
		textPrivateMessage = new javax.swing.JTextField ();
		buttonSendPrivateOk = new javax.swing.JButton ();
		buttonSendPrivateCancel = new javax.swing.JButton ();
		dialogJoinPrivateRoom = new javax.swing.JDialog ();
		labelPrivateRoomPassword = new javax.swing.JLabel ();
		textJoinPrivatePassword = new javax.swing.JPasswordField ();
		buttonJoinPrivateCancel = new javax.swing.JButton ();
		buttonJoinPrivateOk = new javax.swing.JButton ();
		setDialogLogin (new javax.swing.JDialog ());
		labelUserName = new javax.swing.JLabel ();
		setTextUserName (new javax.swing.JTextField ());
		buttonLogin = new javax.swing.JButton ();
		setDialogAlert (new javax.swing.JDialog ());
		setLabelAlert (new javax.swing.JLabel ());
		setButtonAlertOk (new javax.swing.JButton ());
		labelChatHistory = new javax.swing.JLabel ();
		scrollPaneChatHistory = new javax.swing.JScrollPane ();
		setTextChatHistory (new javax.swing.JTextPane ());
		setTextChatMessage (new javax.swing.JTextField ());
		setButtonSend (new javax.swing.JButton ());
		scrollPaneRoomList = new javax.swing.JScrollPane ();
		setListRooms (new javax.swing.JList ());
		labelRoomList = new javax.swing.JLabel ();
		setButtonJoin (new javax.swing.JButton ());
		setButtonNewRoom (new javax.swing.JButton ());
		scrollPaneUserList = new javax.swing.JScrollPane ();
		listUsers = new javax.swing.JList ();
		setButtonSendPrivate (new javax.swing.JButton ());
		labelUserList = new javax.swing.JLabel ();
		setButtonLogout (new javax.swing.JButton ());
		labelCopyright = new javax.swing.JLabel ();

		dialogNewRoom
				.setDefaultCloseOperation (javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		dialogNewRoom.setTitle ("Create New Room");
		dialogNewRoom.setModal (true);
		dialogNewRoom.setName (null);
		dialogNewRoom.setResizable (false);

		labelRoomName.setText ("Room name:");

		labelMaxUsers.setText ("Max. users:");

		labelPassword.setText ("Password (optional):");

		buttonCreateRoomOk.setText ("Create");
		buttonCreateRoomOk
				.addActionListener (new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this
								.buttonCreateRoomOkActionPerformed (evt);
					}
				});

		buttonCreateRoomCancel.setText ("Cancel");
		buttonCreateRoomCancel
				.addActionListener (new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this
								.buttonCreateRoomCancelActionPerformed (evt);
					}
				});

		sliderNewRoomMaxUsers.setMajorTickSpacing (10);
		sliderNewRoomMaxUsers.setMaximum (50);
		sliderNewRoomMaxUsers.setMinimum (10);
		sliderNewRoomMaxUsers.setMinorTickSpacing (10);
		sliderNewRoomMaxUsers.setPaintLabels (true);
		sliderNewRoomMaxUsers.setPaintTicks (true);
		sliderNewRoomMaxUsers.setSnapToTicks (true);

		final javax.swing.GroupLayout dialogNewRoomLayout = new javax.swing.GroupLayout (
				dialogNewRoom.getContentPane ());
		dialogNewRoom.getContentPane ().setLayout (dialogNewRoomLayout);
		dialogNewRoomLayout
				.setHorizontalGroup (dialogNewRoomLayout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								dialogNewRoomLayout
										.createSequentialGroup ()
										.addContainerGap ()
										.addGroup (
												dialogNewRoomLayout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.LEADING)
														.addGroup (
																dialogNewRoomLayout
																		.createParallelGroup (
																				javax.swing.GroupLayout.Alignment.LEADING,
																				false)
																		.addComponent (
																				textNewRoomName,
																				javax.swing.GroupLayout.DEFAULT_SIZE,
																				260,
																				Short.MAX_VALUE)
																		.addComponent (
																				labelRoomName)
																		.addComponent (
																				labelMaxUsers)
																		.addComponent (
																				sliderNewRoomMaxUsers,
																				javax.swing.GroupLayout.DEFAULT_SIZE,
																				javax.swing.GroupLayout.DEFAULT_SIZE,
																				Short.MAX_VALUE)
																		.addComponent (
																				labelPassword)
																		.addComponent (
																				textNewRoomPassword))
														.addGroup (
																dialogNewRoomLayout
																		.createSequentialGroup ()
																		.addComponent (
																				buttonCreateRoomOk)
																		.addPreferredGap (
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent (
																				buttonCreateRoomCancel)))
										.addContainerGap (26,
												Short.MAX_VALUE)));
		dialogNewRoomLayout
				.setVerticalGroup (dialogNewRoomLayout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								dialogNewRoomLayout
										.createSequentialGroup ()
										.addContainerGap ()
										.addComponent (labelRoomName)
										.addPreferredGap (
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent (
												textNewRoomName,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap (18, 18, 18)
										.addComponent (labelMaxUsers)
										.addPreferredGap (
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent (
												sliderNewRoomMaxUsers,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap (18, 18, 18)
										.addComponent (labelPassword)
										.addPreferredGap (
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent (
												textNewRoomPassword,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap (18, 18, 18)
										.addGroup (
												dialogNewRoomLayout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent (
																buttonCreateRoomOk)
														.addComponent (
																buttonCreateRoomCancel))
										.addContainerGap (
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));

		dialogPrivate
				.setDefaultCloseOperation (javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		dialogPrivate.setTitle ("Send Private Message");
		dialogPrivate.setModal (true);
		dialogPrivate.setName (null);
		dialogPrivate.setResizable (false);

		labelPrivateMessage.setText ("Message:");

		buttonSendPrivateOk.setText ("Send");
		buttonSendPrivateOk
				.addActionListener (new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this.sendWhisper_OK (evt);
					}
				});

		buttonSendPrivateCancel.setText ("Cancel");
		buttonSendPrivateCancel
				.addActionListener (new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this.cancelSendingWhisper (evt);
					}
				});

		final javax.swing.GroupLayout dialogPrivateLayout = new javax.swing.GroupLayout (
				dialogPrivate.getContentPane ());
		dialogPrivate.getContentPane ().setLayout (dialogPrivateLayout);
		dialogPrivateLayout
				.setHorizontalGroup (dialogPrivateLayout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								dialogPrivateLayout
										.createSequentialGroup ()
										.addContainerGap ()
										.addGroup (
												dialogPrivateLayout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent (
																textPrivateMessage,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																374,
																Short.MAX_VALUE)
														.addComponent (
																labelPrivateMessage)
														.addGroup (
																dialogPrivateLayout
																		.createSequentialGroup ()
																		.addComponent (
																				buttonSendPrivateOk)
																		.addPreferredGap (
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent (
																				buttonSendPrivateCancel)))
										.addContainerGap ()));
		dialogPrivateLayout
				.setVerticalGroup (dialogPrivateLayout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								dialogPrivateLayout
										.createSequentialGroup ()
										.addContainerGap ()
										.addComponent (
												labelPrivateMessage)
										.addPreferredGap (
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent (
												textPrivateMessage,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap (18, 18, 18)
										.addGroup (
												dialogPrivateLayout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent (
																buttonSendPrivateOk)
														.addComponent (
																buttonSendPrivateCancel))
										.addContainerGap (
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));

		dialogJoinPrivateRoom
				.setDefaultCloseOperation (javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		dialogJoinPrivateRoom.setTitle ("Join Private Room");
		dialogJoinPrivateRoom.setModal (true);
		dialogJoinPrivateRoom.setName (null);
		dialogJoinPrivateRoom.setResizable (false);

		labelPrivateRoomPassword.setText ("Password:");

		buttonJoinPrivateCancel.setText ("Cancel");
		buttonJoinPrivateCancel
				.addActionListener (new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this
								.buttonJoinPrivateCancelActionPerformed (evt);
					}
				});

		buttonJoinPrivateOk.setText ("Join");
		buttonJoinPrivateOk
				.addActionListener (new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this
								.buttonJoinPrivateOkActionPerformed (evt);
					}
				});

		final javax.swing.GroupLayout dialogJoinPrivateRoomLayout = new javax.swing.GroupLayout (
				dialogJoinPrivateRoom.getContentPane ());
		dialogJoinPrivateRoom.getContentPane ().setLayout (
				dialogJoinPrivateRoomLayout);
		dialogJoinPrivateRoomLayout
				.setHorizontalGroup (dialogJoinPrivateRoomLayout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								dialogJoinPrivateRoomLayout
										.createSequentialGroup ()
										.addContainerGap ()
										.addGroup (
												dialogJoinPrivateRoomLayout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent (
																textJoinPrivatePassword,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																210,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent (
																labelPrivateRoomPassword)
														.addGroup (
																dialogJoinPrivateRoomLayout
																		.createSequentialGroup ()
																		.addComponent (
																				buttonJoinPrivateOk)
																		.addPreferredGap (
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent (
																				buttonJoinPrivateCancel)))
										.addContainerGap (
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));
		dialogJoinPrivateRoomLayout
				.setVerticalGroup (dialogJoinPrivateRoomLayout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								dialogJoinPrivateRoomLayout
										.createSequentialGroup ()
										.addContainerGap ()
										.addComponent (
												labelPrivateRoomPassword)
										.addPreferredGap (
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent (
												textJoinPrivatePassword,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap (18, 18, 18)
										.addGroup (
												dialogJoinPrivateRoomLayout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent (
																buttonJoinPrivateOk)
														.addComponent (
																buttonJoinPrivateCancel))
										.addContainerGap (
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));

		getDialogLogin ().setDefaultCloseOperation (
				javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		getDialogLogin ().setTitle ("Login");
		getDialogLogin ().setModal (true);
		getDialogLogin ().setName (null);
		getDialogLogin ().setResizable (false);

		labelUserName.setText ("Type your user name:");

		buttonLogin.setText ("Login");
		buttonLogin
				.addActionListener (new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this.buttonLoginActionPerformed (evt);
					}
				});

		final javax.swing.GroupLayout dialogLoginLayout = new javax.swing.GroupLayout (
				getDialogLogin ().getContentPane ());
		getDialogLogin ().getContentPane ().setLayout (
				dialogLoginLayout);
		dialogLoginLayout
				.setHorizontalGroup (dialogLoginLayout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								dialogLoginLayout
										.createSequentialGroup ()
										.addContainerGap ()
										.addGroup (
												dialogLoginLayout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent (
																getTextUserName (),
																javax.swing.GroupLayout.PREFERRED_SIZE,
																285,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent (
																labelUserName)
														.addComponent (
																buttonLogin))
										.addContainerGap (
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));
		dialogLoginLayout
				.setVerticalGroup (dialogLoginLayout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								dialogLoginLayout
										.createSequentialGroup ()
										.addContainerGap ()
										.addComponent (labelUserName)
										.addPreferredGap (
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent (
												getTextUserName (),
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap (18, 18, 18)
										.addComponent (buttonLogin)
										.addContainerGap (
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));

		getDialogAlert ().setDefaultCloseOperation (
				javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		getDialogAlert ().setTitle ("Alert");
		getDialogAlert ().setModal (true);
		getDialogAlert ().setResizable (false);

		getLabelAlert ().setText ("The alert message goes here...");

		getButtonAlertOk ().setText ("Ok");
		getButtonAlertOk ().addActionListener (
				new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this
								.buttonAlertOkActionPerformed (evt);
					}
				});

		final javax.swing.GroupLayout dialogAlertLayout = new javax.swing.GroupLayout (
				getDialogAlert ().getContentPane ());
		getDialogAlert ().getContentPane ().setLayout (
				dialogAlertLayout);
		dialogAlertLayout
				.setHorizontalGroup (dialogAlertLayout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								dialogAlertLayout
										.createSequentialGroup ()
										.addContainerGap ()
										.addGroup (
												dialogAlertLayout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent (
																getLabelAlert (),
																javax.swing.GroupLayout.DEFAULT_SIZE,
																309,
																Short.MAX_VALUE)
														.addComponent (
																getButtonAlertOk (),
																javax.swing.GroupLayout.Alignment.TRAILING))
										.addContainerGap ()));
		dialogAlertLayout
				.setVerticalGroup (dialogAlertLayout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								dialogAlertLayout
										.createSequentialGroup ()
										.addContainerGap ()
										.addComponent (getLabelAlert ())
										.addPreferredGap (
												javax.swing.LayoutStyle.ComponentPlacement.RELATED,
												18, Short.MAX_VALUE)
										.addComponent (
												getButtonAlertOk ())
										.addContainerGap ()));

		setDefaultCloseOperation (javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setTitle ("SmartFoxJChat");
		setLocationByPlatform (true);
		setMinimumSize (new java.awt.Dimension (660, 650));
		setName ("frmMain"); // NOI18N
		setResizable (false);

		labelChatHistory.setFont (new java.awt.Font ("Tahoma", 1, 14)); // NOI18N
		labelChatHistory.setText ("Chat History");
		labelChatHistory.setName ("labelChatHistory"); // NOI18N

		getTextChatHistory ().setContentType ("text/html");
		getTextChatHistory ().setEditable (false);
		getTextChatHistory ().setName ("textChatHistory"); // NOI18N
		scrollPaneChatHistory.setViewportView (getTextChatHistory ());

		getTextChatMessage ().setEnabled (false);
		getTextChatMessage ().setName ("textChatMessage"); // NOI18N
		getTextChatMessage ().addKeyListener (
				new java.awt.event.KeyAdapter () {
					@Override
					public void keyPressed (
							final java.awt.event.KeyEvent evt) {
						MainFrame.this.sendPublicMessageForKey (evt);
					}
				});

		getButtonSend ().setText ("Send");
		getButtonSend ().setEnabled (false);
		getButtonSend ().addActionListener (
				new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this.sendPublicMessage (evt);
					}
				});

		getListRooms ().setModel (new RoomListModel ());
		getListRooms ().setSelectionMode (
				javax.swing.ListSelectionModel.SINGLE_SELECTION);
		getListRooms ().setCellRenderer (new RoomListCellRenderer ());
		getListRooms ().setName ("listRooms"); // NOI18N
		getListRooms ().addListSelectionListener (
				new javax.swing.event.ListSelectionListener () {
					public void valueChanged (
							final javax.swing.event.ListSelectionEvent evt) {
						MainFrame.this.roomList_changedSelection (evt);
					}
				});
		scrollPaneRoomList.setViewportView (getListRooms ());

		labelRoomList.setFont (new java.awt.Font ("Tahoma", 1, 14)); // NOI18N
		labelRoomList.setText ("Room List");

		getButtonJoin ().setText ("Join");
		getButtonJoin ().setEnabled (false);
		getButtonJoin ().addActionListener (
				new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this.buttonJoinActionPerformed (evt);
					}
				});

		getButtonNewRoom ().setText ("New Room");
		getButtonNewRoom ().setEnabled (false);
		getButtonNewRoom ().addActionListener (
				new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this.newRoom_createDialog (evt);
					}
				});

		listUsers.setModel (new UserListModel ());
		listUsers
				.setSelectionMode (javax.swing.ListSelectionModel.SINGLE_SELECTION);
		listUsers.setCellRenderer (new UserListCellRenderer ());
		listUsers.setVisibleRowCount (20);
		listUsers
				.addListSelectionListener (new javax.swing.event.ListSelectionListener () {
					public void valueChanged (
							final javax.swing.event.ListSelectionEvent evt) {
						MainFrame.this.userList_changedSelection (evt);
					}
				});
		scrollPaneUserList.setViewportView (listUsers);

		getButtonSendPrivate ().setText ("Send Private Message");
		getButtonSendPrivate ().setEnabled (false);
		getButtonSendPrivate ().addActionListener (
				new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this.openWhisperDialog (evt);
					}
				});

		labelUserList.setFont (new java.awt.Font ("Tahoma", 1, 14)); // NOI18N
		labelUserList.setText ("User List");

		getButtonLogout ().setText ("Logout");
		getButtonLogout ().setEnabled (false);
		getButtonLogout ().addActionListener (
				new java.awt.event.ActionListener () {
					public void actionPerformed (
							final java.awt.event.ActionEvent evt) {
						MainFrame.this
								.buttonLogoutActionPerformed (evt);
					}
				});

		labelCopyright.setText ("(c) gotoAndPlay() 2008");

		final javax.swing.GroupLayout layout = new javax.swing.GroupLayout (
				getContentPane ());
		getContentPane ().setLayout (layout);
		layout
				.setHorizontalGroup (layout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								layout
										.createSequentialGroup ()
										.addContainerGap ()
										.addGroup (
												layout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.LEADING)
														.addGroup (
																layout
																		.createSequentialGroup ()
																		.addGroup (
																				layout
																						.createParallelGroup (
																								javax.swing.GroupLayout.Alignment.LEADING)
																						.addComponent (
																								scrollPaneUserList,
																								0,
																								0,
																								Short.MAX_VALUE)
																						.addGroup (
																								layout
																										.createSequentialGroup ()
																										.addComponent (
																												getButtonJoin ())
																										.addPreferredGap (
																												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																										.addComponent (
																												getButtonNewRoom ()))
																						.addComponent (
																								labelUserList)
																						.addComponent (
																								labelRoomList)
																						.addComponent (
																								scrollPaneRoomList,
																								javax.swing.GroupLayout.DEFAULT_SIZE,
																								175,
																								Short.MAX_VALUE))
																		.addPreferredGap (
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addGroup (
																				layout
																						.createParallelGroup (
																								javax.swing.GroupLayout.Alignment.LEADING)
																						.addComponent (
																								labelChatHistory,
																								javax.swing.GroupLayout.PREFERRED_SIZE,
																								107,
																								javax.swing.GroupLayout.PREFERRED_SIZE)
																						.addComponent (
																								scrollPaneChatHistory,
																								javax.swing.GroupLayout.Alignment.TRAILING,
																								javax.swing.GroupLayout.DEFAULT_SIZE,
																								459,
																								Short.MAX_VALUE)))
														.addGroup (
																layout
																		.createSequentialGroup ()
																		.addComponent (
																				getButtonSendPrivate (),
																				javax.swing.GroupLayout.DEFAULT_SIZE,
																				175,
																				Short.MAX_VALUE)
																		.addPreferredGap (
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent (
																				getTextChatMessage (),
																				javax.swing.GroupLayout.DEFAULT_SIZE,
																				325,
																				Short.MAX_VALUE)
																		.addPreferredGap (
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent (
																				getButtonSend (),
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				57,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addPreferredGap (
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent (
																				getButtonLogout ()))
														.addComponent (
																labelCopyright))
										.addContainerGap ()));
		layout
				.setVerticalGroup (layout
						.createParallelGroup (
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup (
								layout
										.createSequentialGroup ()
										.addContainerGap ()
										.addGroup (
												layout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent (
																labelRoomList)
														.addComponent (
																labelChatHistory))
										.addPreferredGap (
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup (
												layout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.LEADING,
																false)
														.addGroup (
																layout
																		.createSequentialGroup ()
																		.addComponent (
																				scrollPaneRoomList,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				200,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addPreferredGap (
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addGroup (
																				layout
																						.createParallelGroup (
																								javax.swing.GroupLayout.Alignment.BASELINE)
																						.addComponent (
																								getButtonJoin ())
																						.addComponent (
																								getButtonNewRoom ()))
																		.addGap (
																				18,
																				18,
																				18)
																		.addComponent (
																				labelUserList)
																		.addPreferredGap (
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent (
																				scrollPaneUserList,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				304,
																				javax.swing.GroupLayout.PREFERRED_SIZE))
														.addComponent (
																scrollPaneChatHistory))
										.addPreferredGap (
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup (
												layout
														.createParallelGroup (
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent (
																getButtonSendPrivate ())
														.addComponent (
																getTextChatMessage (),
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent (
																getButtonSend ())
														.addComponent (
																getButtonLogout ()))
										.addGap (18, 18, 18)
										.addComponent (labelCopyright)
										.addContainerGap (
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));

		pack ();
	}// </editor-fold>//GEN-END:initComponents

	/**
	 * Displays a dialog that allows new room creation.
	 */
	private void newRoom_createDialog (
			final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonNewRoomActionPerformed
		dialogNewRoom.pack ();
		dialogNewRoom.setLocation (getX () + 100, getY () + 100);
		textNewRoomName.setText ("");
		textNewRoomPassword.setText ("");
		sliderNewRoomMaxUsers.setValue (50);
		dialogNewRoom.setVisible (true);
	}// GEN-LAST:event_buttonNewRoomActionPerformed

	/**
	 * Shows dialog that asks for the private message to be send.
	 */
	private void openWhisperDialog (final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonSendPrivateActionPerformed
		dialogPrivate.pack ();
		dialogPrivate.setLocation (getX () + 100, getY () + 100);
		getTextChatMessage ().setText ("");
		dialogPrivate.setVisible (true);
	}// GEN-LAST:event_buttonSendPrivateActionPerformed

	/**
	 * When the user slects new room enables "Join Room" button if the
	 * room is not the current, otherwise disables it.
	 */
	private void roomList_changedSelection (
			final javax.swing.event.ListSelectionEvent evt) {// GEN-FIRST:event_listRoomsValueChanged
		final Room room = (Room) getListRooms ().getSelectedValue ();
		if (room != null && room.getId () != getSfs ().activeRoomId) {
			getButtonJoin ().setEnabled (true);
		} else {
			getButtonJoin ().setEnabled (false);
		}
	}// GEN-LAST:event_listRoomsValueChanged

	/**
	 * Sends public message to the server.
	 */
	private void sendPublicMessage (final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonSendActionPerformed
		if (getTextChatMessage ().getText ().length () > 0) {
			getSfs ().sendPublicMessage (
					getTextChatMessage ().getText ());
			getTextChatMessage ().setText ("");
			getTextChatMessage ().requestFocus ();
		}
	}// GEN-LAST:event_buttonSendActionPerformed

	/**
	 * Sends a public message to the server.
	 */
	private void sendPublicMessageForKey (
			final java.awt.event.KeyEvent evt) {// GEN-FIRST:event_textChatMessageKeyPressed
		if (evt.getKeyCode () == KeyEvent.VK_ENTER) {
			sendPublicMessage (null);
		}
	}// GEN-LAST:event_textChatMessageKeyPressed

	/**
	 * Sends private message to the server.
	 */
	private void sendWhisper_OK (final java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonSendPrivateOkActionPerformed
		final String msg = textPrivateMessage.getText ();
		if (msg.length () > 0) {
			dialogPrivate.dispose ();
			final User recipient = (User) listUsers.getSelectedValue ();
			if (recipient != null) {
				getSfs ().sendPrivateMessage (msg, recipient.getId ());
			}
		}
	}// GEN-LAST:event_buttonSendPrivateOkActionPerformed

	/**
	 * @param buttonAlertOk the buttonAlertOk to set
	 */
	public void setButtonAlertOk (
			final javax.swing.JButton buttonAlertOk) {
		this.buttonAlertOk = buttonAlertOk;
	}

	/**
	 * @param buttonJoin the buttonJoin to set
	 */
	public void setButtonJoin (final javax.swing.JButton buttonJoin) {
		this.buttonJoin = buttonJoin;
	}

	/**
	 * @param buttonLogout the buttonLogout to set
	 */
	public void setButtonLogout (final javax.swing.JButton buttonLogout) {
		this.buttonLogout = buttonLogout;
	}

	/**
	 * @param buttonNewRoom the buttonNewRoom to set
	 */
	public void setButtonNewRoom (
			final javax.swing.JButton buttonNewRoom) {
		this.buttonNewRoom = buttonNewRoom;
	}

	/**
	 * @param buttonSend the buttonSend to set
	 */
	public void setButtonSend (final javax.swing.JButton buttonSend) {
		this.buttonSend = buttonSend;
	}

	/**
	 * @param buttonSendPrivate the buttonSendPrivate to set
	 */
	public void setButtonSendPrivate (
			final javax.swing.JButton buttonSendPrivate) {
		this.buttonSendPrivate = buttonSendPrivate;
	}

	/**
	 * @param chatHistory the chatHistory to set
	 */
	public void setChatHistory (final StringBuilder chatHistory) {
		this.chatHistory = chatHistory;
	}

	/**
	 * @param dialogAlert the dialogAlert to set
	 */
	public void setDialogAlert (final javax.swing.JDialog dialogAlert) {
		this.dialogAlert = dialogAlert;
	}

	/**
	 * @param dialogLogin the dialogLogin to set
	 */
	public void setDialogLogin (final javax.swing.JDialog dialogLogin) {
		this.dialogLogin = dialogLogin;
	}

	/**
	 * @param labelAlert the labelAlert to set
	 */
	public void setLabelAlert (final javax.swing.JLabel labelAlert) {
		this.labelAlert = labelAlert;
	}

	/**
	 * @param listRooms the listRooms to set
	 */
	public void setListRooms (final javax.swing.JList listRooms) {
		this.listRooms = listRooms;
	}

	/**
	 * @param textChatHistory the textChatHistory to set
	 */
	public void setTextChatHistory (
			final javax.swing.JTextPane textChatHistory) {
		this.textChatHistory = textChatHistory;
	}

	/**
	 * @param textChatMessage the textChatMessage to set
	 */
	public void setTextChatMessage (
			final javax.swing.JTextField textChatMessage) {
		this.textChatMessage = textChatMessage;
	}

	/**
	 * @param textUserName the textUserName to set
	 */
	public void setTextUserName (
			final javax.swing.JTextField textUserName) {
		this.textUserName = textUserName;
	}

	/**
	 * When the user slects new user enables "Send Private Message"
	 * button if the user is not the current user, otherwise disables
	 * it.
	 */
	private void userList_changedSelection (
			final javax.swing.event.ListSelectionEvent evt) {// GEN-FIRST:event_listUsersValueChanged
		final User user = (User) listUsers.getSelectedValue ();
		if (user != null && user.getId () != getSfs ().myUserId) {
			getButtonSendPrivate ().setEnabled (true);
		} else {
			getButtonSendPrivate ().setEnabled (false);
		}
	}// GEN-LAST:event_listUsersValueChanged
}
