/**
 * @(#)Scrabble.java	11/03/05
 * 
 * Copyright 2005 3GP01, KCL.
 * 
 * King's College, London hereby disclaims all copyright
 * interest in the program `International Remote Scrabble'
 * (a Scrabble game) written by Kevin Lano and 3GP01.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * The GNU General Public Licence should be contained within licence.txt;
 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA  02110-1301, USA.
 */

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.ListSelectionModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.plaf.ColorUIResource;

/**
 * The Scrabble class contains all the necessary variables and methods to act as a 
 * 'launch-pad' for the real scrabble game.  It constructs the pre-game dialogs
 * and handles all lobby front-end functions (its major component).
 * 
 * @author 3GP01 - Hardev Bhamra, Deepak Chandarana, James Tompkin
 * @version 2.0
 * @see LocalScrabble
 * @see RemoteScrabble
 *
 */

class Scrabble extends JFrame implements ActionListener
{	
	static Scrabble scrabble;
	
	static int remote = 0;
	
	I18n i18n = new I18n();
	
	String[][] dictionaries = getDictionaries();  //dictionaries[i][0] = filepath, dictionaries[i][1] = filename
	
	private static boolean heightChangesNecessary = false;
    private static boolean lanSelSucc = false;
    private static boolean dictSelSucc = false;
	private static boolean rlSelSucc = false;

	private boolean connectionSuccessful = false;
	private boolean connectionFailed = false;
	
	ScrabbleBuilder builder;
	
	Server server; //= new Server();
	Client client; //= new Client();

	String clientName;
	String hostLocation;
	String[] clientNames = new String[4];
	String selectedDictionary;
	
	JTextArea messageArea;
	DefaultListModel listModel;

	int numberOfHints;			//number of hints allowed in a remote game
	int numberOfGamesPlayed = 0; //number of scrabble games played
	int numberOfWindows = 0;	 //number of scrabble game windows open
	
	JTextField nameLine;
	JTextField serverLine;
	JTextField messageLine;
	JButton setNameButton;
	JButton setServerButton;
	JButton sendMessageButton;
	JButton startGameButton;
	JButton leaveServerButton;
	
	//declare ImageIcons for preloading
	ImageIcon enGBuntouchedIcon, enGBrolloverIcon, enGBselectedIcon;
	ImageIcon enUSuntouchedIcon, enUSrolloverIcon, enUSselectedIcon;
	ImageIcon frFRuntouchedIcon, frFRrolloverIcon, frFRselectedIcon;
	ImageIcon ruRUuntouchedIcon, ruRUrolloverIcon, ruRUselectedIcon;
	ImageIcon localuntouchedIcon, localrolloverIcon, localselectedIcon;
	ImageIcon clientuntouchedIcon, clientrolloverIcon, clientselectedIcon;
	ImageIcon serveruntouchedIcon, serverrolloverIcon, serverselectedIcon;
	ImageIcon dictionaryIcon;
	
	Border outlineBorder = BorderFactory.createEtchedBorder(Color.WHITE, Color.GRAY);
	
	static Color baseColor;
	static Color supplementaryColor;
	static Color highlightColor;
	
	//initialise custom colours for GUI
	static Color ivory = new Color(254,254,229);
	static Color darkIvory = new Color(252,252,173);
	static Color turquoise = new Color(1,51,52);			//default base color
	static Color lightTurquoise = new Color(0,102,102);		//default button color
	static Color orange = new Color(255,102,0);				//default highlight color
	
	JFrame frame;

	/**
	 * Scans 'resources/dictionaries/' and picks up what dictionaries are available
	 * at the start of the game.
	 * 
	 * @return String[][] Contains dictionary paths/names
	 */
	public static String[][] getDictionaries()
	{
		File location = new File(System.getProperty("user.dir")
								+ File.separator + "resources"
								+ File.separator + "dictionaries"
								+ File.separator);
		File files[] = location.listFiles();			//get into file array files in directory
		String filePath[] = new String[files.length];	//string array for filePath
		String fileName[] = new String[files.length];
		
		String[][] dictionaries = new String[files.length][2];
		
		for(int i = 0; i < files.length; i++)
		{	 
			filePath[i] = files[i].toString();  //get relative path to dictionaries: looks like "resources/dictionaries/"
   			int index = filePath[i].lastIndexOf(File.separator); //get index of last \ in path
			fileName[i] = filePath[i].substring(index+1, filePath[i].length()-4); //take only the dictionary name
			
			dictionaries[i][0] = filePath[i]; //write to array
			dictionaries[i][1] = fileName[i];
		}
		
		return dictionaries;
	}
	
	/**
	 * Returns the current i18n.
	 * 
	 * @return I18n
	 */
	public I18n getI18n()
	{	
		return scrabble.i18n;	
	}
	
    /**
     * Returns the current ScrabbleBuilder.
     * 
     * @return ScrabbleBuilder
     */
    public ScrabbleBuilder getScrabbleBuilder()
    {	
    	return builder;    
    }
    
	/**
	 * Returns the current JFrame in use.  This is necessary so that other classes
	 * can affect the focus/positioning of the lobby, and also to catch closing of 
	 * the application from different frames and close the server/client before System.exit(0).
	 * 
	 * @return JFrame
	 */
	public JFrame getFrame()
	{	
		return frame;	
	}
	
	/**
	 * Returns the client's name, stored locally here.
	 * 
	 * @return String
	 */
	public String getClientName()
	{	
		return clientName;	
	}
	
	/**
	 * Returns the address of the localHost.  Used for a client connecting to their own server.
	 * 
	 * @return String
	 */
	//return localhost ip (the client will be connecting on the local machine)
	public String getLocalHostAddress()
	{	
		InetAddress i = null;
		try
		{	i = InetAddress.getLocalHost();	
		}
		catch (UnknownHostException e) 
		{	}
		return i.getHostAddress();
	}
	
	/**
	 * Returns the current host location.
	 * 
	 * @return String
	 */
	public String getHostLocation()
	{	
		return hostLocation;	
	}
	
	/**
	 * Returns the number of hints allowed during a remote game.
	 * 
	 * @return int
	 */
	public int getNumberOfHints()
	{	
		return numberOfHints;	
	}
    
    /**
     * Returns the number of windows open.
     * 
     * @return int
     */
    public int getNumberOfWindows()
    {	
    	return numberOfWindows;		
    }
	
	/**
	 * Returns the chat log area of the lobby.
	 * 
	 * @return JTextArea
	 */
	public JTextArea getMessageArea()
	{	
		return messageArea;	
	}		
	
    /**
     * Returns the number of games that have been played.
     * 
     * @return int
     */
    public int getNumberOfGamesPlayed()
    {	
    	return numberOfGamesPlayed;		
    }
    
    /**
     * Increases the number of games that have been played by 1.
     */
    public void incrementNumberOfGamesPlayed()
    {	
    	numberOfGamesPlayed++;	
    }
    	
	/**
	 * Returns true/false depending on whether the screen resolution is large enough
	 * to contain the standard GUI, or whether a reduced GUI should be used instead.
	 * 
	 * @return boolean
	 */
	public boolean isHeightChangesNecessary() 
	{	
		return heightChangesNecessary; 
	}

	/**
	 * Sets the chat log in the lobby to be the input String.
	 * 
	 * @param message The message to append to the chat log.
	 */
	public void setChatLog(String message)
	{	
		messageArea.append(message);
	}
	
	/**
	 * Sets whether a client has connected succesfully to the server, and 
	 * alters certain lobby buttons to reflect this.
	 * 
	 * @param trigger A boolean trigger.
	 */
	public void setConnectionSuccessful(boolean trigger)
	{	
		connectionSuccessful = trigger;
		//set button states in lobby on successful connection
		leaveServerButton.setEnabled(trigger);
		nameLine.setEnabled(!trigger);
		setNameButton.setEnabled(!trigger);
		serverLine.setEnabled(!trigger);
		setServerButton.setEnabled(!trigger);
		messageLine.setEnabled(trigger);			//allow chat
		sendMessageButton.setEnabled(trigger);		//allow chat
	}
	
	/**
	 * Sets the connection attempt to have failed.
	 * 
	 * @param trigger A boolean trigger.
	 */
	public void setConnectionFailed(boolean trigger)
	{	
		connectionFailed = trigger;	
	}
	
	/**
	 * Sets the number of hints in a remote game.
	 * 
	 * @param hints
	 */
	public void setNumberOfHints(int hints)
	{	
		numberOfHints = hints;	
	}

	/**
	 * Sets the start game button in the server lobby to be the value of the trigger.
	 * 
	 * @param trigger
	 */
	public void setStartGameButtonEnabled(boolean trigger)
	{	
		startGameButton.setEnabled(trigger);	
	}
	
    /**
     * Sets the current ScrabbleBuilder to be the input builder.
     * 
     * @param build The ScrabbleBuilder to be used.
     */
    public void setScrabbleBuilder(ScrabbleBuilder build)
    {	
    	builder = build;	
    }
    
    /**
     * Increase or Decrease the number of windows depending on the
     * input String.
     * 
     * @param arith String, ++ for increase, -- for decrease.
     */
    public void arithNumberOfWindows(String arith)
    {	
    	if(arith.equals("++"))
    		numberOfWindows++;
    	else if(arith.equals("--"))
    		numberOfWindows--;
    }
    
	/**
	 * Appends a new client to the display list of players.
	 * 
	 * @param name String name of client.
	 */
	public void appendPlayerToLobbyList(String name)
	{	
		listModel.addElement(name);
	}
	
	/**
	 * Removes a client from the display list of players.
	 * 
	 * @param name String name of client.
	 */
	public void removePlayerFromLobbyList(String name)
	{	
		listModel.removeElement(name);
	}
    
    /**
     * Presents a splash screen whilst the game pre-loads icons.
     * Something of a test to see whether it was beneficial, the group
     * decided to keep it.
     * 
     */
    public void preloadIcons()
    {
    	//need to load all the icons FIRST while waiting at a splash screen
    	//so that the delay between windows is minimised
    	
    	//splash screen
    	JWindow frame = new JWindow();

    	Container contentPane = frame.getContentPane();
    	JLabel splashLabel = new JLabel(new ImageIcon("resources/images/splash.png"));
    	contentPane.add(splashLabel);
    	
    	frame.setSize(640,480);
    	frame.setLocationRelativeTo(null); //centres the frame on the screen
    	frame.setVisible(true);
 
    	//british flag icons
    	enGBuntouchedIcon = new ImageIcon("resources/images/flags/flagEnGBuntouched.png");
    	enGBrolloverIcon = new ImageIcon("resources/images/flags/flagEnGBrollover.png");
    	enGBselectedIcon = new ImageIcon("resources/images/flags/flagEnGBselected.png");
    	//us flag icons
    	enUSuntouchedIcon = new ImageIcon("resources/images/flags/flagEnUSuntouched.png");
    	enUSrolloverIcon = new ImageIcon("resources/images/flags/flagEnUSrollover.png");
    	enUSselectedIcon = new ImageIcon("resources/images/flags/flagEnUSselected.png");
    	//french flag icons
    	frFRuntouchedIcon = new ImageIcon("resources/images/flags/flagFrFRuntouched.png");
    	frFRrolloverIcon = new ImageIcon("resources/images/flags/flagFrFRrollover.png");
    	frFRselectedIcon = new ImageIcon("resources/images/flags/flagFrFRselected.png");
    	//russian flag icons
    	ruRUuntouchedIcon = new ImageIcon("resources/images/flags/flagRuRUuntouched.png");
    	ruRUrolloverIcon = new ImageIcon("resources/images/flags/flagRuRUrollover.png");
    	ruRUselectedIcon = new ImageIcon("resources/images/flags/flagRuRUselected.png");
    	//local icons
    	localuntouchedIcon = new ImageIcon("resources/images/locality/localuntouched.png");
    	localrolloverIcon = new ImageIcon("resources/images/locality/localrollover.png");
    	localselectedIcon = new ImageIcon("resources/images/locality/localselected.png");
    	//client icons
    	clientuntouchedIcon = new ImageIcon("resources/images/locality/clientuntouched.png");
    	clientrolloverIcon = new ImageIcon("resources/images/locality/clientrollover.png");
    	clientselectedIcon = new ImageIcon("resources/images/locality/clientselected.png");
    	//server icons
    	serveruntouchedIcon = new ImageIcon("resources/images/locality/serveruntouched.png");
    	serverrolloverIcon = new ImageIcon("resources/images/locality/serverrollover.png");
    	serverselectedIcon = new ImageIcon("resources/images/locality/serverselected.png");
    	//dictionary icon
    	dictionaryIcon = new ImageIcon("resources/images/dictionary.png");

    	frame.dispose();	//ditch frame now that loading is complete
    }
    
	/**
	 * Presents a dialog for selecting the required Locale.
	 */
	public void selectLanguage()
	{	
		frame = new JFrame("Welcome / Добро Пожаловать / Bienvenue");
		
		Container contentPane = frame.getContentPane();
		contentPane.setLayout(new BorderLayout());
	
		JPanel labelPanel = new JPanel();
		labelPanel.setDoubleBuffered(true);
		labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.Y_AXIS));
		
		JLabel label1 = new JLabel("Please choose a language:");
		JLabel label2 = new JLabel("Пожалуйста выберите язык:"); 
		JLabel label3 = new JLabel("Veuillez choisir une langue:");
		
		labelPanel.add(label1);
		label1.setAlignmentX(Component.CENTER_ALIGNMENT);
		labelPanel.add(label2);
		label2.setAlignmentX(Component.CENTER_ALIGNMENT);
		labelPanel.add(label3);
		label3.setAlignmentX(Component.CENTER_ALIGNMENT);
	
		labelPanel.add(Box.createRigidArea(new Dimension(0, 10)));
	
		JPanel langButtonPanel = new JPanel();
		langButtonPanel.setLayout(new BoxLayout(langButtonPanel, BoxLayout.X_AXIS));
		ButtonGroup group = new ButtonGroup();
		
		JPanel leftButtonPanel = new JPanel();
		leftButtonPanel.setLayout(new BoxLayout(leftButtonPanel, BoxLayout.Y_AXIS));
		JPanel rightButtonPanel = new JPanel();
		rightButtonPanel.setLayout(new BoxLayout(rightButtonPanel, BoxLayout.Y_AXIS));
		
		JRadioButton langEnGB = new JRadioButton("British English", enGBuntouchedIcon, true);
		langEnGB.setRolloverIcon(enGBrolloverIcon);
		langEnGB.setSelectedIcon(enGBselectedIcon);
		langEnGB.setVerticalTextPosition(SwingConstants.CENTER);
		langEnGB.setHorizontalTextPosition(SwingConstants.LEFT);
		langEnGB.setAlignmentX(Component.RIGHT_ALIGNMENT);
		langEnGB.setFocusPainted(false);
		leftButtonPanel.add(langEnGB);
		langEnGB.addActionListener(this);
		group.add(langEnGB);
	  
		JRadioButton langEnUS = new JRadioButton("American English", enUSuntouchedIcon);
		langEnUS.setRolloverIcon(enUSrolloverIcon);
		langEnUS.setSelectedIcon(enUSselectedIcon);
		langEnUS.setVerticalTextPosition(SwingConstants.CENTER);
		langEnUS.setHorizontalTextPosition(SwingConstants.RIGHT);
		langEnUS.setAlignmentX(Component.LEFT_ALIGNMENT);
		langEnUS.setFocusPainted(false);
		rightButtonPanel.add(langEnUS);
		langEnUS.addActionListener(this);
		group.add(langEnUS);
		
		JRadioButton langFrFR = new JRadioButton("Français", frFRuntouchedIcon);
		langFrFR.setRolloverIcon(frFRrolloverIcon);
		langFrFR.setSelectedIcon(frFRselectedIcon);
		langFrFR.setVerticalTextPosition(SwingConstants.CENTER);
		langFrFR.setHorizontalTextPosition(SwingConstants.LEFT);
		langFrFR.setAlignmentX(Component.RIGHT_ALIGNMENT);
		langFrFR.setFocusPainted(false);
		leftButtonPanel.add(langFrFR);
		langFrFR.addActionListener(this);
		group.add(langFrFR);
		
		JRadioButton langRuRU = new JRadioButton("Русский", ruRUuntouchedIcon);
		langRuRU.setRolloverIcon(ruRUrolloverIcon);
		langRuRU.setSelectedIcon(ruRUselectedIcon);
		langRuRU.setVerticalTextPosition(SwingConstants.CENTER);
		langRuRU.setHorizontalTextPosition(SwingConstants.RIGHT);
		langRuRU.setAlignmentX(Component.LEFT_ALIGNMENT);
		langRuRU.setFocusPainted(false);
		rightButtonPanel.add(langRuRU);
		langRuRU.addActionListener(this);
		group.add(langRuRU);
	  
		langButtonPanel.add(leftButtonPanel);
		langButtonPanel.add(rightButtonPanel);
		
		JPanel buttContPanel = new JPanel();
	  	JPanel buttonPanel = new JPanel();
	  	buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
	          
	  	buttonPanel.add(Box.createHorizontalGlue());
	  
	  	JButton langOKButton = new JButton("OK");
	  	buttonPanel.add(langOKButton);
	  	langOKButton.addActionListener(this);
	  	frame.getRootPane().setDefaultButton(langOKButton);
	  	
	  	buttonPanel.add(Box.createRigidArea(new Dimension(5, 0)));

	  	JButton colorsButton = new JButton("Colors");
	  	//buttonPanel.add(colorsButton);
	  	colorsButton.addActionListener(this);
	  	
	  	JButton langCancelButton = new JButton("Cancel / Отменить / Annulez");
	  	buttonPanel.add(langCancelButton);
	  	langCancelButton.addActionListener(this);
	  	
	  	buttonPanel.add(Box.createHorizontalGlue());
	  
	  	buttContPanel.setLayout(new BoxLayout(buttContPanel, BoxLayout.Y_AXIS));
	  	buttContPanel.add(Box.createRigidArea(new Dimension(0, 5)));
	  	buttContPanel.add(buttonPanel);
	  	buttContPanel.add(Box.createRigidArea(new Dimension(0, 5)));
	  
	  	contentPane.add(labelPanel, BorderLayout.NORTH);
	  	contentPane.add(langButtonPanel, BorderLayout.CENTER);
	  	contentPane.add(buttContPanel, BorderLayout.SOUTH);

	   	frame.setIconImage(new ImageIcon("resources/images/icon.png").getImage()); //new icon
	   	frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
	   	frame.setResizable(false);
	  	frame.pack();
	  	frame.setLocationRelativeTo(null); //centres the frame on the screen
	  	frame.setVisible(true);
	}
	
	/**
	 * Presents a dialog asking the user where they would like to play.
	 */
	public void selectLocality()
	{	
		frame = new JFrame(i18n.messages.getString("localityTitle"));
		
		Container contentPane = frame.getContentPane();
		contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
	
		ButtonGroup group = new ButtonGroup();
		
		final JRadioButton clientRB = new JRadioButton(i18n.messages.getString("client"), clientuntouchedIcon);
		clientRB.setRolloverIcon(clientrolloverIcon);
		clientRB.setSelectedIcon(clientselectedIcon);
		clientRB.setVerticalTextPosition(SwingConstants.BOTTOM);
		clientRB.setHorizontalTextPosition(SwingConstants.CENTER);
		clientRB.setFocusPainted(false);
		clientRB.addActionListener(new ActionListener() 
		{	public void actionPerformed(ActionEvent e) 
			{	remote = 2;
			}
		});
		group.add(clientRB);
		
		final JRadioButton serverRB = new JRadioButton(i18n.messages.getString("server"), serveruntouchedIcon);
		serverRB.setRolloverIcon(serverrolloverIcon);
		serverRB.setSelectedIcon(serverselectedIcon);
		serverRB.setVerticalTextPosition(SwingConstants.BOTTOM);
		serverRB.setHorizontalTextPosition(SwingConstants.CENTER);
		serverRB.setFocusPainted(false);
		serverRB.addActionListener(new ActionListener() 
		{	public void actionPerformed(ActionEvent e) 
			{	remote = 1;
			}
		});
		group.add(serverRB);
	  
		JRadioButton localRB = new JRadioButton(i18n.messages.getString("local"), localuntouchedIcon, true);
		localRB.setRolloverIcon(localrolloverIcon);
		localRB.setSelectedIcon(localselectedIcon);
		localRB.setVerticalTextPosition(SwingConstants.BOTTOM);
		localRB.setHorizontalTextPosition(SwingConstants.CENTER);
		localRB.setFocusPainted(false);
		localRB.addActionListener(new ActionListener() 
		{	public void actionPerformed(ActionEvent e) 
			{	remote = 0;
			}
		});
		group.add(localRB);
		
		JPanel csButtonPanel = new JPanel();
		csButtonPanel.setLayout(new BoxLayout(csButtonPanel, BoxLayout.X_AXIS));
		csButtonPanel.add(serverRB);
		csButtonPanel.add(Box.createRigidArea(new Dimension(20,0)));
		csButtonPanel.add(clientRB);
		
		localRB.setSelected(true);
	  
		JPanel buttContPanel = new JPanel();
	  	JPanel buttonPanel = new JPanel();
	  	buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
	          
	  	buttonPanel.add(Box.createHorizontalGlue());
	  
	  	JButton rlsOKButton = new JButton(i18n.messages.getString("ok"));
	  	buttonPanel.add(rlsOKButton);
	
	  	buttonPanel.add(Box.createRigidArea(new Dimension(5, 0)));
	  
	  	JButton rlsCancelButton = new JButton(i18n.messages.getString("cancel"));
	  	buttonPanel.add(rlsCancelButton);
	
	  	buttonPanel.add(Box.createHorizontalGlue());
	  
	  	buttContPanel.setLayout(new BoxLayout(buttContPanel, BoxLayout.Y_AXIS));
	  	buttContPanel.add(Box.createRigidArea(new Dimension(0, 10)));
	  	buttContPanel.add(buttonPanel);
	  	buttContPanel.add(Box.createRigidArea(new Dimension(0, 5)));
	  
	  	JPanel lrPanel = new JPanel();
	  	lrPanel.add(localRB);

	  	contentPane.add(lrPanel);
	  	contentPane.add(Box.createRigidArea(new Dimension(0,20)));
		contentPane.add(csButtonPanel);
		contentPane.add(buttContPanel);
	  	
	  	rlsOKButton.addActionListener(new ActionListener() 
	  	{	public void actionPerformed(ActionEvent e) 
			{	rlSelSucc = true;
				frame.dispose();
			}
	  	});
	  
	  	rlsCancelButton.addActionListener(new ActionListener()
	  	{	public void actionPerformed(ActionEvent e)
	  		{	System.exit(0);
	  		}
	  	});
	  	
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		//Create and set up the content pane.
		frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
		frame.setContentPane(contentPane);
		frame.setResizable(false);
		frame.getRootPane().setDefaultButton(rlsOKButton);
		frame.setIconImage(new ImageIcon("resources/images/icon.png").getImage());//new 's' icon.
		frame.pack();
		frame.setLocationRelativeTo(null);	//centres the frame on the screen
		frame.setVisible(true);
	}
	
	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e)
	{	Object eventSource = e.getSource();

  		if(eventSource instanceof JRadioButton)
  		{	JRadioButton rb = (JRadioButton) eventSource;
  			String command = rb.getText();
  			if(command.equals("British English"))
  			{	i18n.setLanguageAndCountry("en","GB");
  			}
  			else if(command.equals("American English"))
  			{	i18n.setLanguageAndCountry("en","US");
  			}
  			else if(command.equals("Français"))
  			{	i18n.setLanguageAndCountry("fr","FR");
			}
  			else if(command.equals("Русский"))
  			{	i18n.setLanguageAndCountry("ru","RU");
  			}
  		}
		else if (eventSource instanceof JButton)
  		{ 	JButton cb = (JButton) eventSource;
  			String command = cb.getText();
  			if(command.equals("OK"))
  			{	i18n.setCurrentLocale();
  				i18n.setResourceBundle();
  				lanSelSucc = true;
  				frame.dispose(); 				
  			}
  			else if(command.equals("Colors"))
  			{	ColorChooser.createAndShowGUI();
  			}
  			else if(command.equals("Cancel / Отменить / Annulez"))
  			{	System.exit(0);	}
  		}
	}
	
	/**
	 * Creates the lobby interface for remote play.
	 * Handles all actions from the lobby.
	 * 
	 * @param remote Local/Server/Client switch.  0 = local, 1 = server, 2 = client
	 */
	public void createLobby(final int remote)
	{	
		server = new Server();
		client = new Client();
		
		frame = new JFrame(i18n.messages.getString("lobbyTitle"));
		
		Container contentPane = frame.getContentPane();
		contentPane.setLayout(new BorderLayout());
		
		//close server/client connections
		frame.addWindowListener(new WindowAdapter() 
		{	public void windowClosing(WindowEvent e) 
			{	//SERVER LOBBY
				if(remote==1)
				{	if(server.isListening() || server.isGameInProgress())
					{	int s = (int) JOptionPane.showConfirmDialog(null, 
										i18n.messages.getString("lobbyCloseMessage"),
										i18n.messages.getString("lobbyCloseTitle"), 
										JOptionPane.YES_NO_OPTION);
						
						if(s==JOptionPane.YES_OPTION)
						{	closeLobby();
						}
					}
					else
					{	System.exit(0);
					}
				}
				//CLIENT LOBBY
				else if(remote==2)
				{	if(connectionSuccessful)	//is connection up?
					{	client.setMessageOutput(9,null);
					}
					System.exit(0);
				}
			}
		});    
		
		TitledBorder gameEntryB, pListB, gameSettingsB, scrollPaneB, messageEntryB;
		
		JPanel lhs = new JPanel();
		lhs.setLayout(new BoxLayout(lhs, BoxLayout.Y_AXIS));
			
			//line for name entry
			nameLine = new JTextField();
			nameLine.setEditable(true);
			setNameButton = new JButton(i18n.messages.getString("setNameButton"));	//complementary button
			//line for server location entry
			serverLine = new JTextField();
			serverLine.setEnabled(false);
			serverLine.setEditable(true);
			setServerButton = new JButton(i18n.messages.getString("setServerButton"));	//complementary button
			setServerButton.setToolTipText(i18n.messages.getString("lobbyToolTip1"));
			setServerButton.setEnabled(false);
			//messageLine for typing, used to chat in lobby
			messageLine = new JTextField(58);
			messageLine.setEnabled(false);
			sendMessageButton = new JButton(i18n.messages.getString("lobbySendButton"));	//complementary button for messageLine
			sendMessageButton.setEnabled(false);
			//player controls for exiting lobby
			JButton kickButton = new JButton(i18n.messages.getString("lobbyKickButton"));
			kickButton.setToolTipText(i18n.messages.getString("lobbyToolTip2"));
			leaveServerButton = new JButton(i18n.messages.getString("lobbyLeftButton"));
			leaveServerButton.setEnabled(false);
			//server creation button
			final JButton createServerButton = new JButton(i18n.messages.getString("lobbyCreateServerButton"));
			
			setNameButton.setMnemonic(KeyEvent.VK_N);
			setServerButton.setMnemonic(KeyEvent.VK_J);
			sendMessageButton.setMnemonic(KeyEvent.VK_S);
			kickButton.setMnemonic(KeyEvent.VK_K);
			leaveServerButton.setMnemonic(KeyEvent.VK_L);
			createServerButton.setMnemonic(KeyEvent.VK_C);
			
			if(remote == 1)//if server, disable name+button so that server must be created first
			{	nameLine.setEnabled(false);
				setNameButton.setEnabled(false);
			}
			
			//panel for join a game
			JPanel gameEntry = new JPanel();
			gameEntry.setLayout(new BoxLayout(gameEntry, BoxLayout.Y_AXIS));
			gameEntryB = BorderFactory.createTitledBorder(outlineBorder, i18n.messages.getString("lobbyBorderJoin"), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, Color.WHITE);
			gameEntry.setBorder(gameEntryB);
			
			//name entry/button listeners
			nameLine.addActionListener(new ActionListener()
			{	public void actionPerformed(ActionEvent e)
				{	if(nameLine.getText().indexOf("¬") >= 0)	//name entry testing
					{	JOptionPane.showMessageDialog(null, i18n.messages.getString("lobbyNameError1"));
						nameLine.setText("");
					}
					else if(nameLine.getText().equals(""))
					{	JOptionPane.showMessageDialog(null, i18n.messages.getString("lobbyNameError2"));
						nameLine.setText("");					
					}
          	  		else if (nameLine.getText().length() > 20)
          	  		{	JOptionPane.showMessageDialog(null, i18n.messages.getString("scrabble.92")); //$NON-NLS-1$
          	  			nameLine.setText("");
          	  		}
					else
					{	clientName = nameLine.getText();
						if(remote==1)	//if server, dont focus on the serverLine because it isnt there
						{	setServerButton.requestFocus();	}
						else
						{	serverLine.requestFocus();	}
						//System.out.println(clientName);
						serverLine.setEnabled(true);
						setServerButton.setEnabled(true);
					}
				}
			});
			
			setNameButton.addActionListener(new ActionListener()
			{	public void actionPerformed(ActionEvent e)
				{	if(nameLine.getText().indexOf("¬") >= 0)	//name entry testing
					{	JOptionPane.showMessageDialog(null, i18n.messages.getString("lobbyNameError1"));
						nameLine.setText("");
					}
          	  		else if (nameLine.getText().length() > 20)
          	  		{	JOptionPane.showMessageDialog(null, i18n.messages.getString("scrabble.92")); //$NON-NLS-1$
          	  			nameLine.setText("");
          	  		}
					else if(nameLine.getText().equals(""))
					{	JOptionPane.showMessageDialog(null, i18n.messages.getString("lobbyNameError2"));
						nameLine.setText("");					
					}
					else
					{	clientName = nameLine.getText();
						if(remote==1)	//if server, dont focus on the serverLine because it isnt there
						{	setServerButton.requestFocus();	}
						else
						{	serverLine.requestFocus();	}
						//System.out.println(clientName);
						serverLine.setEnabled(true);
						setServerButton.setEnabled(true);
					}
				}
			});

			//server entry/button listener
			serverLine.addActionListener(new ActionListener()
			{	public void actionPerformed(ActionEvent e)
				{	if(remote==1)	//if server controller is wanting to connect, 
						hostLocation = getLocalHostAddress();	//get localhost
					else
						hostLocation = serverLine.getText();
					if(hostLocation.equals(""))
					{	JOptionPane.showMessageDialog(null, i18n.messages.getString("lobbyNameError3"));
						serverLine.setText("");
					}
					else
					{	//System.out.println(hostLocation);
						client.start();
						while(!connectionSuccessful && !connectionFailed)
						{	try 
							{	Thread.sleep(100);	}
							catch (InterruptedException e1) 
							{	//Thread exception
								System.exit(0);
							}
						}
						messageLine.requestFocus();
					}
				}
			});
			
			setServerButton.addActionListener(new ActionListener()
			{	public void actionPerformed(ActionEvent e)
				{	if(remote==1)	//if server controller is wanting to connect, 
						hostLocation = getLocalHostAddress();	//get localhost
					else
						hostLocation = serverLine.getText();
					if(hostLocation.equals(""))
					{	JOptionPane.showMessageDialog(null, i18n.messages.getString("lobbyNameError3"));
						serverLine.setText("");
					}
					else
					{	//System.out.println(hostLocation);
						client.start();
						while(!connectionSuccessful && !connectionFailed)
						{	try 
							{	Thread.sleep(100);	}
							catch (InterruptedException e1) 
							{	//Thread exception
								System.exit(0);	
							}
						}
						messageLine.requestFocus();
						messageLine.setEnabled(true);
						sendMessageButton.setEnabled(true);
					}
				}
			});
			
			//setting up panels for name/server entry, giving a reasonable layout
			JPanel namePanel = new JPanel();
			namePanel.setLayout(new BoxLayout(namePanel, BoxLayout.X_AXIS));
			namePanel.add(Box.createRigidArea(new Dimension(5,0)));
			nameLine.setMaximumSize(new Dimension(200,25));
			namePanel.add(nameLine);
			namePanel.add(setNameButton);
			namePanel.add(Box.createRigidArea(new Dimension(5,0)));
			JPanel serverPanel = new JPanel();
			serverPanel.setLayout(new BoxLayout(serverPanel, BoxLayout.X_AXIS));
			serverPanel.add(Box.createRigidArea(new Dimension(5,0)));
			serverLine.setMaximumSize(new Dimension(200,25));
			if(remote==2)	//dont add serverline if in server lobby - will connect to local ip
			{	serverPanel.add(serverLine);	}
			serverPanel.add(setServerButton);
			serverPanel.add(Box.createRigidArea(new Dimension(5,0)));
			
			gameEntry.add(namePanel);
			gameEntry.add(Box.createRigidArea(new Dimension(0,5)));
			gameEntry.add(serverPanel);
			
			JPanel pList = new JPanel();
			pList.setLayout(new BoxLayout(pList, BoxLayout.X_AXIS));
			pListB = BorderFactory.createTitledBorder(outlineBorder, i18n.messages.getString("lobbyBorderPlayers"), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, Color.WHITE);
			pList.setBorder(pListB);
							
				listModel = new DefaultListModel();
				final JList playerList = new JList(listModel);
				if(remote == 2)	//if client
				playerList.setEnabled(false);
				playerList.setPreferredSize(new Dimension(170,72));
				playerList.setMaximumSize(new Dimension(200,72));
				playerList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
				playerList.setLayoutOrientation(JList.VERTICAL);
				playerList.setVisibleRowCount(4);
				kickButton.addActionListener(new ActionListener()
				{	public void actionPerformed(ActionEvent e)
					{	int toKick = playerList.getSelectedIndex();
						if(toKick != -1)	//must have a selected item
						{	setChatLog(playerList.getSelectedValue() + i18n.messages.getString("lobbyChatLog1") + "\n");
							server.playerLeft = true;
							//connectionSuccessful = false;
							server.st[toKick].kick();
							//server.st[toKick].close();	//call close method on server thread of uid to kick
							server.st[toKick] = null;
							listModel.remove(toKick);
						}
					}
				});
				leaveServerButton.addActionListener(new ActionListener()
				{	public void actionPerformed(ActionEvent e)
					{	if(connectionSuccessful)	//is connection up?
						{	client.setMessageOutput(9,null);
							setChatLog(i18n.messages.getString("lobbyChatLog2") + "\n");
						}
					}
				});
				
			pList.add(Box.createRigidArea(new Dimension(5,0)));	
			playerList.setAlignmentY(Component.BOTTOM_ALIGNMENT);				
			pList.add(playerList);
			if(remote == 1)	//if server, give kick control
			{	kickButton.setAlignmentY(Component.BOTTOM_ALIGNMENT);	
				pList.add(kickButton);	}
			if(remote == 2) //if client, give leave control
			{	leaveServerButton.setAlignmentY(Component.BOTTOM_ALIGNMENT);
				pList.add(leaveServerButton);	}
			pList.add(Box.createRigidArea(new Dimension(5,0)));
			
			JPanel gameSettings = new JPanel();
			gameSettings.setLayout(new BoxLayout(gameSettings, BoxLayout.Y_AXIS));
			gameSettingsB = BorderFactory.createTitledBorder(outlineBorder, i18n.messages.getString("lobbyBorderSetup"), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, Color.WHITE);
			gameSettings.setBorder(gameSettingsB);
			//labels for spinniers/comboboxes
			JLabel dictLabel = new JLabel(i18n.messages.getString("lobbyDictLabel"));
			JLabel numPlayersLabel = new JLabel(i18n.messages.getString("lobbyNPLabel"));
			JLabel numHintsLabel = new JLabel(i18n.messages.getString("lobbyNHLabel"));
			//model info for number of players spinner
			SpinnerNumberModel spinnerModel = new SpinnerNumberModel(2,1,4,1); //initial, min, max, step
			//number of player spinner
			final JSpinner numPlayersSpinner = new JSpinner(spinnerModel);
			JFormattedTextField numPlayersTf = ((JSpinner.DefaultEditor)numPlayersSpinner.getEditor()).getTextField();
			numPlayersTf.setEditable(false);
			numPlayersTf.setBackground(Color.WHITE);
			//model info for number of players spinner
			SpinnerNumberModel hintsSpinnerModel = new SpinnerNumberModel(3,0,10,1); //initial value, min, max, increment
			//number of player spinner
			final JSpinner numHintsSpinner = new JSpinner(hintsSpinnerModel);
			JFormattedTextField hintsTf = ((JSpinner.DefaultEditor)numHintsSpinner.getEditor()).getTextField();
			hintsTf.setEditable(false);
			hintsTf.setBackground(Color.WHITE);
		
			
			//get dictionaries
			Object dictList[] = new Object[dictionaries.length+1];
			for(int i = 0; i < dictionaries.length; i++)
			{	dictList[i] = dictionaries[i][1];
			}
			dictList[dictionaries.length] = i18n.messages.getString("dictionarySelectOther");
			
			final JComboBox dictSelect = new JComboBox(dictList);
			
			//start game button
			startGameButton = new JButton(i18n.messages.getString("lobbyStartGameButton"), new ImageIcon("resources/images/locality/startgameuntouched.png"));
			startGameButton.setEnabled(false);
			startGameButton.setDisabledIcon(new ImageIcon("resources/images/locality/startgameuntouched.png"));
			startGameButton.setPressedIcon(new ImageIcon("resources/images/locality/startgameselected.png"));
			startGameButton.setRolloverIcon(new ImageIcon("resources/images/locality/startgamerollover.png"));
			startGameButton.setBorder(null);
			startGameButton.setBackground(new Color(1,51,52));
			
			createServerButton.addActionListener(new ActionListener()
			{	public void actionPerformed(ActionEvent e)
				{	if(dictSelect.getSelectedItem().toString().equals(i18n.messages.getString("dictionarySelectOther")))
					{	File chosenDict = Dictionary.loadOtherDict();	//filechooser
						String nameDict = chosenDict.getName();			//get filename
						Dictionary.copyDictToDictionaries(chosenDict, nameDict);	//copy file to resources/dictionaries/"filename"
						setChatLog(i18n.messages.getString("lobbyChatLog3") + chosenDict + "\n"); //output to message area
						nameDict = nameDict.substring(0, nameDict.length()-4);
						server.start(nameDict, Integer.parseInt(numPlayersSpinner.getValue().toString()), Integer.parseInt(numHintsSpinner.getValue().toString()));			//start server with new dictionary
						createServerButton.setEnabled(false);
						numPlayersSpinner.setEnabled(false);
						numHintsSpinner.setEnabled(false);
						dictSelect.setEnabled(false);
						nameLine.setEnabled(true);
						setNameButton.setEnabled(true);
						//startGameButton.setEnabled(true);
					}
					else
					{	selectedDictionary = dictSelect.getSelectedItem().toString();
						server.start(selectedDictionary, Integer.parseInt(numPlayersSpinner.getValue().toString()), Integer.parseInt(numHintsSpinner.getValue().toString()));
						createServerButton.setEnabled(false);
						numPlayersSpinner.setEnabled(false);
						numHintsSpinner.setEnabled(false);
						dictSelect.setEnabled(false);
						nameLine.setEnabled(true);
						setNameButton.setEnabled(true);
						//startGameButton.setEnabled(true);
					}
				}
			});

			startGameButton.addActionListener(new ActionListener()
				{	public void actionPerformed(ActionEvent e)
					{	//call method on server, telling server to message all clients
						//server needs to randomly generate a 'uid', send this to all clients
						//once received, client loads current dictionary
						//client loads board
						//System.out.println("Game Starting");
						//server.setListening(false);
						server.setGameInProgress(true);
						startGameButton.setEnabled(false);
						startGameButton.setDisabledIcon(new ImageIcon("resources/images/locality/startgameselected.png"));
						startGameButton.setText(i18n.messages.getString("lobbySGInProgress"));
					}
				}
			);
						
			//panel for number of players 
			JPanel numPlayersPanel = new JPanel();
			numPlayersPanel.setLayout(new BoxLayout(numPlayersPanel, BoxLayout.X_AXIS));
			numPlayersPanel.add(Box.createRigidArea(new Dimension(5,0)));
			numPlayersPanel.add(numPlayersLabel);
			numPlayersPanel.add(Box.createHorizontalGlue());
			numPlayersSpinner.setPreferredSize(new Dimension(35,25));
			numPlayersSpinner.setMaximumSize(new Dimension(35,25));
			numPlayersPanel.add(numPlayersSpinner);
			numPlayersPanel.add(Box.createRigidArea(new Dimension(5,0)));
			//panel for number of hints
			JPanel numHintsPanel = new JPanel();
			numHintsPanel.setLayout(new BoxLayout(numHintsPanel, BoxLayout.X_AXIS));
			numHintsPanel.add(Box.createRigidArea(new Dimension(5,0)));
			numHintsPanel.add(numHintsLabel);
			numHintsPanel.add(Box.createHorizontalGlue());
			numHintsSpinner.setPreferredSize(new Dimension(35,25));
			numHintsSpinner.setMaximumSize(new Dimension(35,25));
			numHintsPanel.add(numHintsSpinner);
			numHintsPanel.add(Box.createRigidArea(new Dimension(5,0)));
			//panel for dictionary select
			JPanel dictSelPanel = new JPanel();
			dictSelPanel.setLayout(new BoxLayout(dictSelPanel, BoxLayout.X_AXIS));
			dictSelPanel.add(Box.createRigidArea(new Dimension(10,0)));
			dictSelPanel.add(dictLabel);
			dictSelPanel.add(Box.createHorizontalGlue());
			dictSelect.setMaximumSize(new Dimension(40,25));
			dictSelPanel.add(dictSelect);
			dictSelPanel.add(Box.createRigidArea(new Dimension(10,0)));
						
			gameSettings.add(numPlayersPanel);
			gameSettings.add(numHintsPanel);
			gameSettings.add(dictSelPanel);
			gameSettings.add(Box.createRigidArea(new Dimension(0,10)));
			if(remote==1)
			{	createServerButton.setAlignmentX(Component.CENTER_ALIGNMENT);
				gameSettings.add(createServerButton);
			}
			//add a graphic to the lobby, make it look a little nicer
			JLabel lobbyLogo = new JLabel(new ImageIcon("resources/images/locality/lobby.png"));
			lobbyLogo.setAlignmentX(Component.CENTER_ALIGNMENT);
			lhs.add(lobbyLogo);
			lhs.add(Box.createVerticalGlue());
			gameSettings.setAlignmentX(Component.CENTER_ALIGNMENT);
			if(remote==1)
				lhs.add(gameSettings);
			gameEntry.setAlignmentX(Component.CENTER_ALIGNMENT);
			lhs.add(gameEntry);
			pList.setAlignmentX(Component.CENTER_ALIGNMENT);
			lhs.add(pList);
			startGameButton.setAlignmentX(Component.CENTER_ALIGNMENT);
			if(remote == 1)	//add start game button at bottom
				lhs.add(startGameButton);
		
		messageArea = new JTextArea();
		messageArea.setEditable(false);
		messageArea.setLineWrap(true);
		JScrollPane scrollPane = new JScrollPane(messageArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		scrollPane.setPreferredSize(new Dimension(400,400));
		scrollPaneB = BorderFactory.createTitledBorder(outlineBorder, i18n.messages.getString("lobbyBorderChatLog"), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, Color.WHITE);
		scrollPane.setBorder(scrollPaneB);
		
		JPanel messageEntry = new JPanel();
		messageEntryB = BorderFactory.createTitledBorder(outlineBorder, i18n.messages.getString("lobbyBorderChat"), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, Color.WHITE);
		messageEntry.setBorder(messageEntryB);
		
		messageLine.addActionListener(new ActionListener()
		{	public void actionPerformed(ActionEvent e)
			{	client.setMessageOutput(10, messageLine.getText());
				messageLine.setText("");
			}
		});
		
		messageLine.setEditable(true);
		
		sendMessageButton.addActionListener(new ActionListener()
		{	public void actionPerformed(ActionEvent e)
			{	client.setMessageOutput(10, messageLine.getText());
				messageLine.setText("");
			}
		});
		
		messageEntry.add(messageLine);
		messageEntry.add(sendMessageButton);
		
		contentPane.add(lhs, BorderLayout.WEST);
		contentPane.add(scrollPane, BorderLayout.CENTER);
		contentPane.add(messageEntry, BorderLayout.SOUTH);
		
		frame.setContentPane(contentPane);
		frame.setResizable(true);

		frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		frame.setIconImage(new ImageIcon("resources/images/icon.png").getImage());//new 's' icon.
		frame.pack();
		frame.setLocationRelativeTo(null);	//centres the frame on the screen
		frame.setVisible(true);
	}
	
	/**
	 * Reset the state of the lobby so that another game may take place.
	 * Clients wait in a queue until the server has chosen new options for the new game, 
	 * after which the clients are reconnected.
	 */
	public void resetLobby()
	{	server.gameInProgress = false;
		startGameButton.setEnabled(false);
		startGameButton.setText(i18n.messages.getString("lobbyStartGameButton"));
	}
	

	/**
	 * 	Method to close connections and dispose of the lobby - this method is called at the end of the game.
	 */
	public void closeLobby()
	{	
		if(remote==1)//if server lobby
		{	server.close();
		}
		else if(remote==2)//if client lobby
		{	if(connectionSuccessful)	//is connection up?
			{	client.setMessageOutput(9,null);
			}
		}
		System.exit(0);
	}
	
	/**
	 * Presents a dialog to the user for selecting a dictionary.
	 * Dictionaries in the list are those found with the <code>getDictionaries()</code> method.
	 */
	public void selectDictionary()
	{	
		ImageIcon icon = new ImageIcon("resources/images/dictionary.png"); //image for box
		//get dictionaries
		Object [] dictList = new Object[dictionaries.length+1];
		for(int i = 0; i < dictionaries.length; i++)
		{	dictList[i] = dictionaries[i][1];
		}
		dictList[dictionaries.length] = i18n.messages.getString("dictionarySelectOther");
		
		//need some i18n-able buttons in here
		String n = (String)JOptionPane.showInputDialog(
	          null,
	          i18n.messages.getString("dictionarySelectRequest"),
	          i18n.messages.getString("dictionarySelectMenuTitle"),
	          JOptionPane.PLAIN_MESSAGE,
	          icon,
	          dictList,
	          null);
		
		if(n == null)
		{	System.exit(0);	}
		else if (n.equals(i18n.messages.getString("dictionarySelectOther")))
		{	Dictionary.loadFromFile(n, null);	//load and copy into resources/dictionaries for future use
			builder = new ScrabbleBuilder();
			dictSelSucc = true;
		}
		else
		{	for(int i = 0; i < dictionaries.length; i++)
			{	if(n.equals(dictList[i]))
				{	Dictionary.loadFromFile(n, dictionaries[i][0]);
					builder = new ScrabbleBuilder();
					dictSelSucc = true;
					break;
				}
			}
		}
	}
	
	public static void updateUIDefaults()
	{
		try 
		{  	
			/* This code enables the app to use the look and feel of the host system
		  	 * However, currently this messes up the board colours when windows has non-default colours, so its commented out
		  	 * When (if) we switch to an image based board (shouldnt be too difficult)
		  	 * then this can be re-enabled.
		  	 *
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
			*/
			UIDefaults defaults = UIManager.getDefaults();
			
			defaults.put("ToolTip.background", new ColorUIResource(supplementaryColor));
			defaults.put("ToolTip.foreground", new ColorUIResource(Color.WHITE));
			defaults.put("Panel.background", new ColorUIResource(baseColor));
			
			defaults.put("ScrollPane.background", new ColorUIResource(baseColor));
			
			defaults.put("ScrollBar.background", new ColorUIResource(Color.WHITE));
			defaults.put("ScrollBar.thumb", new ColorUIResource(supplementaryColor));
			
			defaults.put("ProgressBar.background", new ColorUIResource(Color.WHITE));
			defaults.put("ProgressBar.foreground", new ColorUIResource(supplementaryColor));
			
			//Border paddingBorder = BorderFactory.createMatteBorder(3,15,3,15,supplementaryColor);
			//Border outlineBorder = BorderFactory.createEtchedBorder(Color.WHITE, Color.GRAY);
			//Border border = BorderFactory.createCompoundBorder(outlineBorder, paddingBorder);	
			defaults.put("ButtonUI","MouseOverButtonUI");
			defaults.put("Button.background", new ColorUIResource(supplementaryColor));
			defaults.put("Button.foreground", new ColorUIResource(Color.WHITE));
			//defaults.put("Button.border", border);
					
			defaults.put("RadioButton.background", new ColorUIResource(baseColor));
			defaults.put("RadioButton.foreground", new ColorUIResource(Color.WHITE));
			
			defaults.put("Label.foreground", new ColorUIResource(Color.WHITE));
			
			defaults.put("OptionPane.background", new ColorUIResource(baseColor));
			defaults.put("OptionPane.messageForeground", new ColorUIResource(Color.WHITE));
			
			defaults.put("ComboBox.background", new ColorUIResource(supplementaryColor));
			defaults.put("ComboBox.foreground", new ColorUIResource(Color.WHITE));
			defaults.put("ComboBox.disabledBackground", new ColorUIResource(supplementaryColor));
			defaults.put("ComboBox.selectionBackground", new ColorUIResource(highlightColor));
			defaults.put("ComboBox.selectionForeground", new ColorUIResource(Color.WHITE));
			
			defaults.put("List.selectionBackground", new ColorUIResource(highlightColor));
			defaults.put("List.selectionForeground", new ColorUIResource(Color.WHITE));
		} 
	 	catch (Exception e) { }
	
	}
	
	/**
	 * Checks to see if the OS is Windows XP or not - now not needed
	 * as linux implementation is working fine.
	 * This required simple changes to the protocol/dictionary loading
	 * 
	 * @deprecated This is no longer used as IRS runs ok in unix based OS's
	 *
	 */
	public void checkOSName()
	{	if(!System.getProperty("os.name").equals("Windows XP"))
		{	//this exception here is because we are having difficulties with the unix path
			//for loading dictionaries.  it is an 'anything but' clause atm purely because we dont
			//have time to test it fully.
			JOptionPane.showMessageDialog(null, "Current IRS does not support anything but Windows XP.  We are working on this issue, please accept our apologies.",
					"OS error", JOptionPane.ERROR_MESSAGE);
			System.exit(0);
		}
	}
	
	/**
	 * Checks to see whether the current screen resolution is supported or not.
	 * Certain ammendments are made to the GUI if the resolution is between 768 and 864 pixels high.
	 * Resolutions lower than 768 pixels high are not supported by IRS.
	 */
	public void checkResolution()
	{	
		Dimension screenResolution = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
		int screenHeight = screenResolution.height;
		//if screen res is less than 768 tall, exit (we dont support it)
		if(screenHeight < 768)
		{	JOptionPane.showMessageDialog(null, i18n.messages.getString("resErrMessage"),
												i18n.messages.getString("resErrTitle"), JOptionPane.ERROR_MESSAGE);
			System.exit(0);
		}
		else if (screenHeight >=768 && screenHeight < 864)
		{	heightChangesNecessary = true;
		}
	}
	
	/**
	 * Creates and shows the 'pre-game' dialogs, and then launches either LocalScrabble
	 * or RemoteScrabble depending on the user's choices.
	 * Custom GUI colours are set here using UIManager.
	 * 
	 */
	public static void createAndShowGUI()
	{	
		//set custom UI colors, defined defaults are used
		baseColor = turquoise;
		supplementaryColor = lightTurquoise;
		highlightColor = orange;
		
		updateUIDefaults();
		
		JFrame.setDefaultLookAndFeelDecorated(true);	//applied after splash screen loads
		JDialog.setDefaultLookAndFeelDecorated(true);	//so that splash screen is borderless
		
		scrabble = new Scrabble();
		
		scrabble.preloadIcons();
		
		scrabble.selectLanguage();
		while(!lanSelSucc)
		{	try {	Thread.sleep(100);	}
			catch(InterruptedException e) {	e.printStackTrace();	}
		}
		
		scrabble.checkResolution();
		scrabble.selectLocality();
		while(!rlSelSucc)
		{	try {	Thread.sleep(100);	} 
			catch (InterruptedException e) {	e.printStackTrace();	}
		}
		if(remote == 0)						//local game
		{	scrabble.selectDictionary();
			LocalScrabble.createAndShowGUI();
		}
		else if (remote == 1)				//remote game, as server
		{	scrabble.createLobby(remote);	//go to lobby - select name, select dictionary, reject players, pass messages
		}
		else if (remote == 2)				//remote game, as client
		{	scrabble.createLobby(remote);	//go to lobby - select name, pass messages
		}
	}
	
	/**
	 * Execution method of International Remote Scrabble.
	 *  
	 * @param args Arguments passed at runtime.
	 */
	public static void main(String[] args)
	{	
		createAndShowGUI();
	}
}
