package com.atlassian.uwc.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.AbstractButton;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import regexdemo.AppRegexDemo;
import regexdemo.FrameRegexDemo;

import com.atlassian.uwc.ui.UWCUserSettings.Setting;
import com.atlassian.uwc.ui.listeners.AddPagesListener;
import com.atlassian.uwc.ui.listeners.ChangeAttachmentCheckboxListener;
import com.atlassian.uwc.ui.listeners.ChangeCheckboxListener;
import com.atlassian.uwc.ui.listeners.CheckboxObserver;
import com.atlassian.uwc.ui.listeners.ConvertListener;
import com.atlassian.uwc.ui.listeners.EnableTextFieldObserver;
import com.atlassian.uwc.ui.listeners.ExportWikiListener;
import com.atlassian.uwc.ui.listeners.GuiDisablingListener;
import com.atlassian.uwc.ui.listeners.HasAllConvertSettingsListener;
import com.atlassian.uwc.ui.listeners.IgnoreAltListener;
import com.atlassian.uwc.ui.listeners.LaunchFeedbackListener;
import com.atlassian.uwc.ui.listeners.PageHandler;
import com.atlassian.uwc.ui.listeners.RemovePagesListener;
import com.atlassian.uwc.ui.listeners.SaveListener;
import com.atlassian.uwc.ui.listeners.SelectFileDropTargetListener;
import com.atlassian.uwc.ui.listeners.TestSettingsListener;
import com.atlassian.uwc.ui.listeners.UrlLauncher;
import com.atlassian.uwc.ui.listeners.WikiIsExportableListener;

/**
 * Improved GUI for the UWC
 */
public class UWCForm3 {

	//CONSTANTS
	protected static final String UWC_DOC_URL = "https://studio.plugins.atlassian.com/wiki/display/UWC/";
	private static final String DEFAULT_DIR_LABEL = "Attachments";
	public static final String UWC_DOC_WEBSITE = UWC_DOC_URL + "Universal+Wiki+Converter";
	private static final String PASSWORD_TOOLTIP = "The password to the Confluence user account being used in the Login field.";
	private static final String SPACE_TOOLTIP = "This is the spacekey of the Confluence space you will be importing files to.";
	private static final String ATTACHMENTS_TOOLTIP = "This is the directory where attachments are kept for your particular wiki. This setting will be wiki dependent, so check the appropriate Help docs for more info.";
	private static final String LOGIN_TOOLTIP = "This is the username of an account on the Confluence server with write privileges to the space where you\'re adding content.";
	private static final String ADDRESS_TOOLTIP = "This is the url to Confluence. Example: 'localhost:8080'";
	private static final String VERSION_INDICATOR = ""; 
	public static final String VERSION_NUMBER = "4.0-SNAPSHOT-090712";
	private static final Dimension TABBEDPANE_SIZE = new Dimension(420, 475);
	public static final String APP_NAME = "Universal Wiki Converter";
	private static final int BASIC_RIGHT_MARGIN = 35;
	private static final int MED_WIDTH = 185;
	private static final int MED_HEIGHT = 18;
	private static final Dimension MED_SIZE = new Dimension(MED_WIDTH, MED_HEIGHT);
	private static final int BASE_INSET = 5;
	private static final int LABEL_RIGHT_MARGIN = 5;
	private static final int LABEL_LEFT_MARGIN = 55;
	/**
	 * default directory where properies are located
	 */
	private static final String PROPS_DIR = "conf";  

	//Swing objects
	private JFrame jFrame = null;  
	private JPanel jContentPane = null;
	private JFrame aboutDialog = null;  //  @jve:decl-index=0:visual-constraint="510,12"
	private JPanel aboutContentPane = null;
	private UWCLabel aboutVersionLabel = null;
	private JTabbedPane jTabbedPane = null;
	private JPanel jPanelBasic = null;
	private JPanel jPanelAdvanced = null;
	private UWCLabel jLabelType = null;
	private JComboBox jComboBox_WikiType = null;
	private JButton jButtonExport = null;
	private JPanel jPanelFromLabel = null;
	private UWCGuiLine line1 = null;
	private UWCGuiLine line2 = null;
	private JLabel jLabelDirectory = null;
	protected JTextField jTextFieldAttachments = null;
	private JButton jButtonDirectory = null;
	private JLabel jLabelPages = null;
	private JScrollPane jScrollPanePages = null;
	private JList jListPages = null;
	private JButton jButtonAddPages = null;
	private JButton jButtonRemovePages = null;
	private JPanel jPanelToLabel = null;
	private UWCGuiLine line3 = null;
	private UWCGuiLine line4 = null;
	private UWCLabel jLabelAddress = null;
	private JTextField jTextFieldAddress = null;
	private UWCLabel jLabelLogin = null;
	private JTextField jTextFieldLogin = null;
	private UWCLabel jLabelPass = null;
	private JPasswordField jPasswordField = null;
	private UWCLabel jLabelSpace = null;
	private JTextField jTextFieldSpace = null;
	private JPanel jPanelMain = null;
	private JButton jButtonConvert = null;
	private JButton jButtonClose = null;
	private JCheckBox jCheckBoxSendToConfluence = null;
	private JButton jButtonTestConnection = null;
	private TestSettingsListener testSettingsListener;
	private JButton jButtonLaunchRegexTester = null;
	private UWCLabel jLabelSendToConfluence = null;
	private JPanel jPanel_OptSettings;
	private UWCGuiLine line5;
	private UWCGuiLine line6;
	private JPanel jPanel_Tools;
	private UWCGuiLine line7;
	private UWCGuiLine line8;
	private UWCLabel jLabelTestConnection;
	private UWCLabel jLabelLaunchRegexTester;
	private FrameRegexDemo regexFrame;
	private JCheckBox jCheckBoxFeedbackOption;
	private UWCLabel jLabelFeedbackOption;
	private JButton jButtonLaunchFeedback;
	private UWCLabel jLabelLaunchFeedback;
	private FeedbackWindow feedbackWindow;
	private JCheckBox jCheckBoxAttachmentSize = null;
	private JLabel jLabelAttachmentSize = null;
	private JTextField jTextFieldAttachmentSize = null;

	/* Menu objects */
	
	private JMenuBar jJMenuBar = null;
	private JMenu fileMenu = null;
	private JMenu helpMenu = null;
	private JMenuItem exitMenuItem = null;
	private JMenuItem aboutMenuItem = null;
	private JMenuItem saveMenuItem = null;
	private JMenu converterMenu = null;
	private JMenu viewMenu = null;
	private JMenu toolsMenu = null;
	private JMenuItem convertMenuItem = null;
	private JMenuItem exportMenuItem = null;
	private JMenuItem addMenuItem = null;
	private JMenuItem removeMenuItem = null;
	private JMenuItem conversionTabMenuItem = null;
	private JMenuItem otherToolsTabMenuItem = null;
	private JCheckBoxMenuItem sendPagesCheckboxMenuItem = null;
	private JCheckBoxMenuItem launchFeedbackCheckboxMenuItem = null;
	private JCheckBoxMenuItem attachmentSizeCheckboxMenuItem = null;
	private JMenuItem testConnectionMenuItem = null;
	private JMenuItem regexTesterMenuItem = null;
	private JMenuItem launchFeedbackMenuItem = null;
	private JMenu whenConvertingMenu = null;
	private JMenu onlineDocMenu = null;
	private JMenuItem uwcMainDoc = null;
	private JMenuItem quickDoc = null;
	private JMenuItem sslDoc = null;
	private JMenuItem guiDoc = null;

	/* Listeners */
	private ChangeCheckboxListener sendPagesCheckboxListener;
	private ChangeCheckboxListener launchFeedbackCheckboxListener;
	private ChangeCheckboxListener attachmentSizeCheckboxListener;
	private ActionListener regexLauncher;  
	private LaunchFeedbackListener launchFeedbackListener;
	private Vector<Integer> availableWikiHelpDocMnemonics;
	private HasAllConvertSettingsListener hasAllConvertSettingsListener;
	private AddPagesListener addPagesListener;
	private RemovePagesListener removePagesListener;
	private ChangeCheckboxListener attachmentSizeMenuItemListener;
	private SelectFileDropTargetListener dragnDropListener;

	/* General Objects*/
	Logger log = Logger.getLogger(this.getClass());  
	private HashMap<String, JMenuItem> wikiHelpMenuItems; 
	/**
	 * contains access to all the necessary state, underlying data, settings
	 */
	UWCGuiModel model = null;  
	/**
	 * overriding properties directory. If this is null, then
	 * PROPS_DIR will be used.
	 */
	private static String commandLineArgDir;

	/* Methods */
	
	/**
	 * autosaves settings, and shuts down the UWC
	 */
	void shutdownUWC() {
//		preShutdownCleanup(); //XXX This should get called by the shutdown hook. See ShutDownController
		System.exit(0);
	}

	/**
	 * handles all the UWC cleanup needed before exiting the program.
	 * called from ShutDownController
	 */
	protected void preShutdownCleanup() {
		log.debug("Shutting Down...");
		save();
	}

	/**
	 * saves all the settings to the file system as properties
	 */
	private void save() {
		Setting unsavedKey = this.model.getUnsaved();
		if (unsavedKey != null) {
			String value = getFormValue(unsavedKey);
			if (SaveListener.valid(unsavedKey, value)) {
				//log it but hide passwords
				String printVal = getPrintablePassword(unsavedKey, value);
				log.debug("Saving last form element: '" + unsavedKey + "' = '" + printVal +"'");
				this.model.saveSetting(unsavedKey, value);
			}
			else {
				log.warn("Unsaved form element: " + unsavedKey + " is invalid. Not saving.");
			}
		}
		this.model.saveAllSettings();
	}

	/**
	 * gets the value allowed to be shown to anyone, based on the given setting and value
	 * @param setting
	 * @param value
	 * @return masks the value, if appropriate. Example, if the setting is
	 * <table>
	 * <tr><td>setting</td><td>value</td><td>returns</td></tr>
	 * <tr><td>PASSWORD</td><td>1234</td><td>*******</td></tr>
	 * <tr><td>SPACE</td><td>key</td><td>key</td></tr>
	 * </table>
	 */
	private String getPrintablePassword(Setting setting, String value) {
		String printVal = value;
		if (setting == Setting.PASSWORD) {
			printVal = "*******";
		}
		return printVal;
	}
	
	/**
	 * gets the value for the given key. only enabled for
	 * URL, LOGIN, PASSWORD, SPACE, and ATTACHMENT_SIZE.
	 * 
	 * @param setting given key
	 * @return the value or null, if this method is not supported with the
	 * given key
	 * @throws IllegalArgumentException if the given setting is null
	 */
	public String getFormValue(Setting setting) {
		if (setting == null) throw new IllegalArgumentException("unsavedKey parameter may not be null");
		switch (setting) {
		case URL:
			return getJTextfieldAddress().getText();
		case LOGIN:
			return getJTextFieldLogin().getText();
		case PASSWORD:
			return SaveListener.getPasswordData(getJPasswordField());
		case SPACE:
			return getJTextFieldSpace().getText();
		case ATTACHMENT_SIZE:
			return getJTextFieldAttachmentSize().getText();
		case ATTACHMENTS:
			return getJTextFieldAttachments().getText();
		default:
			log.warn("Not handling element: " + setting);	
		}
		return null;
	}
	
	/* Swing Object Getters/Creators */

	/**
	 * creates or gets the container which handles the 
	 * tabs.	
	 */
	private JTabbedPane getJTabbedPane() {
		if (jTabbedPane == null) {
			jTabbedPane = new JTabbedPane();
			jTabbedPane.setFont(UWCLabel.getUWCFont());
			//title, icon, component, tip
			jTabbedPane.addTab("Conversion Settings", null, getJPanelBasic(), null);
			jTabbedPane.addTab("Other Tools", null, getJPanelAdvanced(), null);
			//set the current tab from settings
			jTabbedPane.setSelectedIndex(
					Integer.parseInt(
							model.getSetting(
									UWCUserSettings.Setting.CURRENT_TAB)));
			//create listener to save current tab as a setting
			jTabbedPane.addChangeListener(new ChangeListener() {
				public void stateChanged(ChangeEvent event) {
					JTabbedPane pane = (JTabbedPane) event.getSource();
					int index = pane.getSelectedIndex();
					log.debug("Saving Current Tab = " + index);
					model.saveSetting(UWCUserSettings.Setting.CURRENT_TAB, index + "");
				}
			});
		}
		return jTabbedPane;
	}

	/**
	 * creates or gets the panel reflecting
	 * the main UI elements contained in the 
	 * Conversion Settings tab	
	 */
	private JPanel getJPanelBasic() {
		if (jPanelBasic == null) {
			
			jPanelBasic = new JPanel();
			jPanelBasic.setLayout(new GridBagLayout());
			jPanelBasic.setPreferredSize(TABBEDPANE_SIZE);
			
			//convert from wiki label
			GridBagConstraints gridBagConstraints_jPanelFromLabel = getHeaderLabelConstraints(0);
			gridBagConstraints_jPanelFromLabel.weightx = 0.1;
			getJPanelFromLabel();
			
			//type label
			jLabelType = new UWCLabel();
			jLabelType.setText("Type:");
			GridBagConstraints gridBagConstraints_jLabelType = getBaseLabelConstraints(1);

			//wikitypes combobox
			GridBagConstraints gridBagConstraints_jComboBoxWikiType = getBaseConstraints();
			gridBagConstraints_jComboBoxWikiType.gridx = 1;
			gridBagConstraints_jComboBoxWikiType.gridy = 1;
			gridBagConstraints_jComboBoxWikiType.gridwidth = 2;
			gridBagConstraints_jComboBoxWikiType.fill = GridBagConstraints.BOTH;
			
			
			//export button
			GridBagConstraints gridBagConstraints_jButtonExport = getBaseConstraints();
			gridBagConstraints_jButtonExport.gridx = 3;
			gridBagConstraints_jButtonExport.gridy = 1;
			gridBagConstraints_jButtonExport.insets = new Insets(BASE_INSET,BASE_INSET,BASE_INSET, BASIC_RIGHT_MARGIN);
						
			//directory label
			jLabelDirectory = new UWCLabel();
			jLabelDirectory.setText(getDirectoryLabel()+":");
			jLabelDirectory.setToolTipText(ATTACHMENTS_TOOLTIP);

			//browse for dir button
			GridBagConstraints gridBagConstraints_jButtonDirectory = getBaseConstraints();
			gridBagConstraints_jButtonDirectory.gridx = 3;
			gridBagConstraints_jButtonDirectory.gridy = 3;
			gridBagConstraints_jButtonDirectory.insets = new Insets(BASE_INSET,BASE_INSET,BASE_INSET, BASIC_RIGHT_MARGIN);

			//pages label
			jLabelPages = new UWCLabel();
			jLabelPages.setText("Pages:");
			
			//pages list (in a scroll pane)
			GridBagConstraints gridBagConstraints_jScrollPages = getBaseConstraints();
			gridBagConstraints_jScrollPages.gridx = 1;
			gridBagConstraints_jScrollPages.gridy = 4;
			gridBagConstraints_jScrollPages.gridwidth = 3;
			gridBagConstraints_jScrollPages.gridheight = 7;
			gridBagConstraints_jScrollPages.fill = GridBagConstraints.BOTH;
			gridBagConstraints_jScrollPages.weighty = 0.75; 
			gridBagConstraints_jScrollPages.insets = new Insets(BASE_INSET,BASE_INSET,BASE_INSET, BASIC_RIGHT_MARGIN);
			
			//add page button
			GridBagConstraints gridBagConstraints_jButtonAdd = getBaseConstraints();
			gridBagConstraints_jButtonAdd.gridx = 1;
			gridBagConstraints_jButtonAdd.gridy = GridBagConstraints.RELATIVE;
			gridBagConstraints_jButtonAdd.anchor = GridBagConstraints.FIRST_LINE_START;
			
			//remove page button
			GridBagConstraints gridBagConstraints_jButtonRemove = getBaseConstraints();
			gridBagConstraints_jButtonRemove.gridx = 2;
			gridBagConstraints_jButtonRemove.gridy = GridBagConstraints.RELATIVE;
			gridBagConstraints_jButtonRemove.anchor = GridBagConstraints.FIRST_LINE_START;

			//to label
			GridBagConstraints gridBagConstraints_jPanelToLabel = getHeaderLabelConstraints(GridBagConstraints.RELATIVE);

			//add components to jPanelBasic
			jPanelBasic.add(getJPanelFromLabel(), gridBagConstraints_jPanelFromLabel);
			jPanelBasic.add(jLabelType, gridBagConstraints_jLabelType);
			jPanelBasic.add(getJComboBox_WikiType(), gridBagConstraints_jComboBoxWikiType);
			jPanelBasic.add(getJButtonExport(), gridBagConstraints_jButtonExport);
			jPanelBasic.add(jLabelDirectory, getBaseLabelConstraints(3));
			jPanelBasic.add(getJTextFieldAttachments(), getBaseSettingsConstraints(3));
			jPanelBasic.add(getJButtonAttachments(), gridBagConstraints_jButtonDirectory);
			jPanelBasic.add(jLabelPages, getBaseLabelConstraints(4));
			jPanelBasic.add(getJScrollPanePages(), gridBagConstraints_jScrollPages);
			jPanelBasic.add(getJButtonAdd(), gridBagConstraints_jButtonAdd);
			jPanelBasic.add(getJButtonRemovePages(), gridBagConstraints_jButtonRemove);
			jPanelBasic.add(getJPanelToLabel(), gridBagConstraints_jPanelToLabel);
			jPanelBasic.add(getJLabelAddress(), getBaseLabelConstraints(GridBagConstraints.RELATIVE));
			jPanelBasic.add(getJTextfieldAddress(), getToConfluenceTextfieldContraints(13));
			jPanelBasic.add(getJLabelLogin(), getBaseLabelConstraints(14));
			jPanelBasic.add(getJTextFieldLogin(), getToConfluenceTextfieldContraints(14));
			jPanelBasic.add(getJLabelPass(), getBaseLabelConstraints(15));
			jPanelBasic.add(getJPasswordField(), getToConfluenceTextfieldContraints(15));
			jPanelBasic.add(getJLabelSpace(), getBaseLabelConstraints(16));
			jPanelBasic.add(getJTextFieldSpace(), getToConfluenceTextfieldContraints(16));
		}
		return jPanelBasic;
	}

	/**
	 * @return the contents of the label for the directory field. 
	 * Note: this was encapuslated in a field to provide a spot for
	 * a possible new feature: extracting an optional non-converter property
	 * which would provide the wiki specific label, using the default label when 
	 * the property is not supplied
	 */
	private String getDirectoryLabel() {
		//XXX Possibly use a non-converter property to extract a wiki specific label?
		return DEFAULT_DIR_LABEL;
	}

	/**
	 * creates or gets the label for the space field
	 */
	private UWCLabel getJLabelSpace() {
		if (jLabelSpace == null) {
			jLabelSpace = new UWCLabel();
			jLabelSpace.setText("Space Key:");
			jLabelSpace.setToolTipText(SPACE_TOOLTIP);
		}
		return jLabelSpace;
	}

	/**
	 * creates or gets the label for the password field
	 */
	private UWCLabel getJLabelPass() {
		if (jLabelPass == null) {
			jLabelPass = new UWCLabel();
			jLabelPass.setText("Password:");
			jLabelPass.setToolTipText(PASSWORD_TOOLTIP);
		}
		return jLabelPass;
	}

	/**
	 * creates or gets the label for the login field
	 */
	private UWCLabel getJLabelLogin() {
		if (jLabelLogin == null) {
			jLabelLogin = new UWCLabel();
			jLabelLogin.setText("Login:");
			jLabelLogin.setToolTipText(LOGIN_TOOLTIP);
		}
		return jLabelLogin;
	}

	/**
	 * creates or gets the address textfield
	 */
	private JTextField getJTextfieldAddress() {
		if (jTextFieldAddress == null) {
			jTextFieldAddress = new JTextField();
			jTextFieldAddress.setFont(UWCLabel.getUWCFont());
			jTextFieldAddress.setToolTipText(ADDRESS_TOOLTIP);
			
			SaveListener saveListener = new SaveListener(
										this.jTextFieldAddress, 
										this.model, 
										Setting.URL,
										this.feedbackWindow 
								);
			jTextFieldAddress.addActionListener(saveListener);
			jTextFieldAddress.addFocusListener(saveListener);
			jTextFieldAddress.addFocusListener(getHasAllListener());
			jTextFieldAddress.addKeyListener(new IgnoreAltListener(jTextFieldAddress));
			jTextFieldAddress.getDocument().addDocumentListener(getHasAllListener());

			jTextFieldAddress.setText(this.model.getSetting(Setting.URL));
			
		}
		return jTextFieldAddress;
	}

	/**
	 * creates or gets the label for the address field
	 */
	private UWCLabel getJLabelAddress() {
		if (jLabelAddress == null) {
			jLabelAddress = new UWCLabel();
			jLabelAddress.setText("Address:");
			jLabelAddress.setToolTipText(ADDRESS_TOOLTIP);
		}
		return jLabelAddress;
	}

	/**
	 * creates or gets the wikitype dropdown menu
	 */
	private JComboBox getJComboBox_WikiType() {
		if (jComboBox_WikiType == null) {
			jComboBox_WikiType = new JComboBox();
			jComboBox_WikiType.setFont(UWCLabel.getUWCFont());
			jComboBox_WikiType.setPreferredSize(MED_SIZE);
			jComboBox_WikiType.setModel(getWikiTypes());
			
			jComboBox_WikiType.addActionListener(
					new WikiIsExportableListener(
							jComboBox_WikiType,
							getJButtonExport(),
							this.model,
							getPropsDir()
							));
			jComboBox_WikiType.addActionListener(
					new WikiIsExportableListener(
							jComboBox_WikiType,
							getExportMenuItem(),
							this.model,
							getPropsDir()
							));
			jComboBox_WikiType.addActionListener(
					new SaveListener(
							this.jComboBox_WikiType,
							this.model,
							Setting.WIKITYPE,
							this.feedbackWindow
					));
			jComboBox_WikiType.addActionListener(
					new GuiDisablingListener(
							this.jComboBox_WikiType,
							getPropsDir(),
							this.feedbackWindow,
							this
					));
			jComboBox_WikiType.addActionListener(getHasAllListener());
			jComboBox_WikiType.setSelectedItem(this.model.getSetting(Setting.WIKITYPE));
		}
		return jComboBox_WikiType;
	}

	/**
	 * @return the directory where properties are located.
	 * The default value is PROPS_DIR.
	 */
	private String getPropsDir() {
		return (commandLineArgDir == null)?PROPS_DIR:commandLineArgDir;
	}

	/**
	 * @return a model that will provide the available wiki types,
	 * based on the existing converter.xxx.properties files in existence
	 */
	protected ComboBoxModel getWikiTypes() {
		Vector wikitypes = model.getWikiTypesList(getPropsDir());
		ComboBoxModel cbModel = new DefaultComboBoxModel(wikitypes);
		cbModel.setSelectedItem(null);
		return cbModel;
	}

	/**
	 * creates or gets the Export button
	 */
	private JButton getJButtonExport() {
		if (jButtonExport == null) {
			jButtonExport = new JButton();
			jButtonExport.setText("Export");
			jButtonExport.setFont(UWCLabel.getUWCFont());
//			this gets set as a result of an event triggered by the wikitypes combobox
			jButtonExport.setEnabled(false); 
			jButtonExport.addActionListener(new ExportWikiListener(
					jComboBox_WikiType,
					this.model,
					getPropsDir(),
					getFeedbackWindow()));
		}
		return jButtonExport;
	}

	/**
	 * creates or gets the From Confluence header label
	 */
	private JPanel getJPanelFromLabel() {
		if (jPanelFromLabel == null) {
			jPanelFromLabel = createLineLabel(
					jPanelFromLabel, 
					line1, 
					line2, 
					"Convert From Wiki", 50);
		}
		return jPanelFromLabel;
	}

	/**
	 * creates or gets the To Confluence header label
	 */
	private JPanel getJPanelToLabel() {
		if (jPanelToLabel == null) {
			
			jPanelToLabel = createLineLabel(
					jPanelToLabel,
					line3,
					line4,
					"To Confluence", 50);
		}
		return jPanelToLabel;
	}

	/**
	 * creates a panel which visibly represents 
	 * an app wide label with headers and decorative lines
	 * @param panel We pass this in because we want to use fields for these objects,
	 * <i>and</i> we might want them to be different for different usages of this method.
	 * @param line1 see panel
	 * @param line2 see panel
	 * @param text Label's visible text
	 * @param leftMargin left column's left margin
	 * @return
	 */
	private JPanel createLineLabel(
			JPanel panel, 
			UWCGuiLine line1, 
			UWCGuiLine line2, 
			String text, 
			int leftMargin) {
		
		panel = new JPanel();
		
		int width = 107;
		
		line1 = new UWCGuiLine(0, 5, width, 5);
		line2 = new UWCGuiLine(0, 5, width, 5);

		UWCLabel label = new UWCLabel();
		label.setText(text);
		label.setHorizontalAlignment(SwingConstants.CENTER); 
		Dimension size = label.getPreferredSize();
		size.width -= 40;
		label.setPreferredSize(size);

		panel.setLayout(new GridBagLayout());


		/*
		 * NOTE: The layout for these panels is
		 * a delicate balancing act between the
		 * weightx, anchors, and margins.
		 * The anchor for each object is CENTER,
		 * set in the getHeaderConstraintsByColumn method.
		 * 
		 * As far as I can tell, a decent English translation of these 
		 * constraint instructions would go something like:
		 * First: give the left line a left margin of 50px.
		 * Second: Divide the remaining space into 3 chunks, such that:
		 * - label's chunk is half of line2's, and
		 * - line1's chunk is 7/10 of line2's
		 * Last: Center the objects into their particular chunk of space
		 * 
		 * The purpose is to place line1 close to the left edge of label
		 * and line2 close to the right edge of label
		 */

		/* 
		 * line 1 contraints need different insets 
		 * so that the first line is placed correctly.
		 */
		GridBagConstraints line1Constraints = getHeaderConstraintsByColumn(0, 0.7);  
		line1Constraints.insets = new Insets(BASE_INSET, leftMargin, BASE_INSET, BASE_INSET);

		panel.add(line1, line1Constraints);
		panel.add(label, getHeaderConstraintsByColumn(1, 0.5));
		panel.add(line2, getHeaderConstraintsByColumn(2, 1.0));
		
		return panel;
	}

	/**
	 * creates or gets attachment directory component 
	 */
	private JTextField getJTextFieldAttachments() {
		if (jTextFieldAttachments == null) {
			jTextFieldAttachments = new JTextField();
			jTextFieldAttachments.setFont(UWCLabel.getUWCFont());
			jTextFieldAttachments.setToolTipText(ATTACHMENTS_TOOLTIP);
			
			//saving events
			SaveListener saveListener = new SaveListener(
										this.jTextFieldAttachments, 
										this.model, 
										Setting.ATTACHMENTS,
										this.feedbackWindow 
								);
			jTextFieldAttachments.addActionListener(saveListener);
			jTextFieldAttachments.addFocusListener(saveListener);
			jTextFieldAttachments.addKeyListener(new IgnoreAltListener(jTextFieldAttachments));
			//loading setting
			jTextFieldAttachments.setText(this.model.getSetting(Setting.ATTACHMENTS));
		}
		return jTextFieldAttachments;
	}

	/**
	 * creates or gets the browse button for the attachment's textfield 
	 */
	private JButton getJButtonAttachments() {
		if (jButtonDirectory == null) {
			jButtonDirectory = new JButton();
			jButtonDirectory.setText("Browse");
			jButtonDirectory.setFont(UWCLabel.getUWCFont());
			jButtonDirectory.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent event) {
					//code grabbed from http://www.exampledepot.com/egs/javax.swing.filechooser/CreateDlg.html
					JFileChooser dialog = new JFileChooser();
				    dialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				    // Show open dialog; this method does not return until the dialog is closed
				    int result = dialog.showOpenDialog(new JFrame());
				    if (result == JFileChooser.APPROVE_OPTION) {
				    	File dirFile = dialog.getSelectedFile();
				    	jTextFieldAttachments.setText(dirFile.getPath());
				    	//save the field
				    	jTextFieldAttachments.getActionListeners()[0].actionPerformed(
				    			new ActionEvent(event.getSource(), event.getID(), SaveListener.DEFAULT_COMMAND));
				    }
				    	
				}
			});
			
		}
		return jButtonDirectory;
	}

	/**
	 * creates or gets the pages panel which displays the chosen pages to be converted
	 */
	private JScrollPane getJScrollPanePages() {
		if (jScrollPanePages == null) {
			jScrollPanePages = new JScrollPane(getJListPages());
			jScrollPanePages.setFont(UWCLabel.getUWCFont());

				
			jScrollPanePages.addMouseListener(getAddPagesListener());
			jScrollPanePages.setDropTarget(new DropTarget(
					jScrollPanePages, 
					DnDConstants.ACTION_COPY, //allowed actions
					getDragnDropListener(), //listener that handles drag-n-drop events
					true //pane is accepting drops
					));
			getJListPages().setDropTarget(new DropTarget(
					jListPages,
					DnDConstants.ACTION_COPY,
					getDragnDropListener(),
					true
			));
		}
		return jScrollPanePages;
	}
	
	private JList getJListPages() {
		if (this.jListPages == null) {
			//pages are from confluenceSetting.properties
			Vector<String> filenames = this.model.getPageNames();
			if (filenames == null || filenames.isEmpty())
				this.jListPages = new JList();
			else
				this.jListPages = new JList(filenames); 
			this.jListPages.setFont(UWCLabel.getUWCFont());
		}
		return this.jListPages;
	}


	private SelectFileDropTargetListener getDragnDropListener() {
		if (this.dragnDropListener == null) {
			dragnDropListener = new SelectFileDropTargetListener(jScrollPanePages, this.model);
			//observers
			dragnDropListener.addObserver(getRemoveButtonEnabledListener());
			dragnDropListener.addObserver(getHasAllListener());
			dragnDropListener.addObserver(new SaveListener(
					getJListPages(),
					this.model,
					Setting.PAGES,
					this.feedbackWindow
			));
		}
		return dragnDropListener;
	}

	/**
	 * creates or gets the add pages button 
	 */
	private JButton getJButtonAdd() {
		if (jButtonAddPages == null) {
			jButtonAddPages = new JButton();
			jButtonAddPages.setText("Add");
			jButtonAddPages.setFont(UWCLabel.getUWCFont());
			AddPagesListener addPagesListener = getAddPagesListener();
			jButtonAddPages.addActionListener(addPagesListener);
			
		}
		return jButtonAddPages;
	}
	
	/**
	 * @return this form's model
	 */
	UWCGuiModel getModel() {
		return this.model;
	}

	/**
	 * creates or gets the remove button  
	 */
	JButton getJButtonRemovePages() {
		if (jButtonRemovePages == null) {
			jButtonRemovePages = new JButton();
			jButtonRemovePages.setText("Remove");
			jButtonRemovePages.setFont(UWCLabel.getUWCFont());
			RemovePagesListener removePagesListener = getRemovePagesListener();
			jButtonRemovePages.addActionListener(removePagesListener);
			
			jButtonRemovePages.setEnabled(!model.getPageFiles().isEmpty());
		}
		return jButtonRemovePages;
	}

	/**
	 * creates or gets the login textfield  
	 */
	private JTextField getJTextFieldLogin() {
		if (jTextFieldLogin == null) {
			jTextFieldLogin = new JTextField();
			jTextFieldLogin.setFont(UWCLabel.getUWCFont());
			jTextFieldLogin.setToolTipText(LOGIN_TOOLTIP);
			
			SaveListener saveListener = new SaveListener(
										this.jTextFieldLogin, 
										this.model, 
										Setting.LOGIN,
										this.feedbackWindow 
								);
			jTextFieldLogin.addActionListener(saveListener);
			jTextFieldLogin.addFocusListener(saveListener);
			jTextFieldLogin.addFocusListener(getHasAllListener());
			jTextFieldLogin.addKeyListener(new IgnoreAltListener(jTextFieldLogin));
			jTextFieldLogin.getDocument().addDocumentListener(getHasAllListener());
			
			jTextFieldLogin.setText(this.model.getSetting(Setting.LOGIN));
		}
		return jTextFieldLogin;
	}

	/**
	 * creates or gets the password field  
	 */
	private JPasswordField getJPasswordField() {
		if (jPasswordField == null) {
			jPasswordField = new JPasswordField();
			jPasswordField.setFont(UWCLabel.getUWCFont());
			jPasswordField.setToolTipText(PASSWORD_TOOLTIP);
			
			SaveListener saveListener = new SaveListener(
										this.jPasswordField, 
										this.model, 
										Setting.PASSWORD,
										this.feedbackWindow 
								);
			jPasswordField.addActionListener(saveListener);
			jPasswordField.addFocusListener(saveListener);
			jPasswordField.addKeyListener(new IgnoreAltListener(jPasswordField));
			jPasswordField.getDocument().addDocumentListener(getHasAllListener());
			
			jPasswordField.setText(this.model.getSetting(Setting.PASSWORD));
		}
		return jPasswordField;
	}

	/**
	 * creates or gets the space textfield  
	 */
	private JTextField getJTextFieldSpace() {
		if (jTextFieldSpace == null) {
			jTextFieldSpace = new JTextField();
			jTextFieldSpace.setFont(UWCLabel.getUWCFont());
			jTextFieldSpace.setToolTipText(SPACE_TOOLTIP);
			
			//saving events
			SaveListener saveListener = new SaveListener(
										this.jTextFieldSpace, 
										this.model, 
										Setting.SPACE,
										this.feedbackWindow 
								);
			jTextFieldSpace.addActionListener(saveListener);
			jTextFieldSpace.addFocusListener(saveListener);
			jTextFieldSpace.addFocusListener(getHasAllListener());
			jTextFieldSpace.addKeyListener(new IgnoreAltListener(jTextFieldSpace));
			jTextFieldSpace.getDocument().addDocumentListener(getHasAllListener());
			
			//loading from settings
			jTextFieldSpace.setText(this.model.getSetting(Setting.SPACE));
		}
		return jTextFieldSpace;
	}

	/**
	 * creates or gets the advanced settings panel.	
	 */
	private JPanel getJPanelAdvanced() {
		if (jPanelAdvanced == null) {
			
			jPanelAdvanced = new JPanel();
			jPanelAdvanced.setLayout(new GridBagLayout());
			jPanelAdvanced.setPreferredSize(TABBEDPANE_SIZE);
			
			GridBagConstraints constraints_OptSettings = getHeaderLabelConstraints(0);
			constraints_OptSettings.weightx = 0.1;
			constraints_OptSettings.gridwidth = 2;
			constraints_OptSettings.insets = new Insets(BASE_INSET, BASE_INSET, BASE_INSET, BASIC_RIGHT_MARGIN);

			GridBagConstraints constraints_Tools = getHeaderLabelConstraints(5);
			constraints_Tools.weightx = 0.1;
			constraints_Tools.gridwidth = 2;
			int moreVerticalSpace = 30;
			constraints_Tools.insets = new Insets(moreVerticalSpace, BASE_INSET, BASE_INSET, BASIC_RIGHT_MARGIN);

			int row = 0;
			jPanelAdvanced.add(getJPanelOptSettings(), constraints_OptSettings);
			row++;
			jPanelAdvanced.add(getJCheckBoxSendToConfluence(), getAdvancedButtonConstraints(row));
			jPanelAdvanced.add(getJLabelSendToConf(), getAdvancedLabelConstraints(row++));
			jPanelAdvanced.add(getJCheckBoxFeedbackOption(), getAdvancedButtonConstraints(row));
			jPanelAdvanced.add(getJLabelFeedbackOption(), getAdvancedLabelConstraints(row++));
			jPanelAdvanced.add(getJCheckBoxAttachmentSize(), getAdvancedButtonConstraints(row));
			jPanelAdvanced.add(getJLabelAttachmentSize(), getAttachSizeLabelConstraints(row++));	
			jPanelAdvanced.add(getJTextFieldAttachmentSize(), getAttachSizeTextFieldConstraints(row++));
			jPanelAdvanced.add(getJPanelTools(), constraints_Tools);
			row++;
			jPanelAdvanced.add(getJButtonTestConnection(), getAdvancedButtonConstraints(row));
			jPanelAdvanced.add(getJLabelTestConnection(), getAdvancedLabelConstraints(row++));
			jPanelAdvanced.add(getJButtonLaunchRegexTester(), getAdvancedButtonConstraints(row));
			jPanelAdvanced.add(getJLabelLaunchRegexTester(), getAdvancedLabelConstraints(row++));
			jPanelAdvanced.add(getJButtonLaunchFeedback(), getAdvancedButtonConstraints(row));
			jPanelAdvanced.add(getJLabelLaunchFeedback(), getAdvancedLabelConstraints(row++));
		}
		return jPanelAdvanced;
	}

	/**
	 * creates or gets the label for the attachment size setting
	 */
	private JLabel getJLabelAttachmentSize() {
		if (jLabelAttachmentSize == null) {
			jLabelAttachmentSize = new UWCLabel();
			String text = 
					"<html>" +
					"Restrict Uploaded Attachment Size." +
					"<br>" +
					"Max File Size:" +
					"</html>";
			jLabelAttachmentSize.setText(text);
			jLabelAttachmentSize.setPreferredSize(new Dimension(200, 40));
		}
		return jLabelAttachmentSize;
	}

	/**
	 * creates or gets the Optional Settings header label
	 */
	private JPanel getJPanelOptSettings() {
		if (jPanel_OptSettings == null) {
			jPanel_OptSettings = createLineLabel(
					jPanel_OptSettings, 
					line5, 
					line6, 
					"Optional Settings", 40);
		}
		return jPanel_OptSettings;
	}

	/**
	 * creates or gets the Developer Tools header label
	 */
	private JPanel getJPanelTools() {
		if (jPanel_Tools == null) {
			jPanel_Tools = createLineLabel(
					jPanel_Tools, 
					line7, 
					line8, 
					"Developer Tools", 40);
		}
		return jPanel_Tools;
	}

	/**
	 * creates or gets the label for the Send Pages To Confluence setting 
	 */
	private UWCLabel getJLabelSendToConf() {
		if (jLabelSendToConfluence == null) {
			jLabelSendToConfluence = new UWCLabel();
			String text = "<html>" +
					"Pages will be sent to Confluence" +
					"<br>" +
					"at the end of the conversion, if this is checked." +
					"</html>";
			jLabelSendToConfluence.setText(text);
			jLabelSendToConfluence.setPreferredSize(new Dimension(200, 50));
		}
		return jLabelSendToConfluence;
	}
	
	/**
	 * creates or gets the label for the Launch Feedback After Convert or Export option
	 */
	private UWCLabel getJLabelFeedbackOption() {
		if (jLabelFeedbackOption == null) {
			jLabelFeedbackOption = new UWCLabel();
			String text = 
					"<html>" +
					"Launch Feedback Window" +
					"<br>" +
					"after convert or export"
					+ "</html>";
			jLabelFeedbackOption.setText(text);
			jLabelFeedbackOption.setPreferredSize(new Dimension(200, 50));
		}
		return jLabelFeedbackOption;
	}
	
	/**
	 * creates or gets the label for the test connection button
	 */
	private UWCLabel getJLabelTestConnection() {
		if (jLabelTestConnection == null) {
			jLabelTestConnection = new UWCLabel();
			String text = "Test the Confluence Server Settings";
			jLabelTestConnection.setText(text);
		}
		return jLabelTestConnection;
	}
	
	/**
	 * creates or gets the label for the regex tester button
	 */
	private UWCLabel getJLabelLaunchRegexTester() {
		if (jLabelLaunchRegexTester == null) {
			jLabelLaunchRegexTester = new UWCLabel();
			String text = "Launch the Regex Tester";
			jLabelLaunchRegexTester.setText(text);
		}
		return jLabelLaunchRegexTester;
	}

	/**
	 * creates or gets the label for the launch feedback button
	 */
	private UWCLabel getJLabelLaunchFeedback() {
		if (jLabelLaunchFeedback == null) {
			jLabelLaunchFeedback = new UWCLabel();
			String text = "Launch the Feedback Window";
			jLabelLaunchFeedback.setText(text);
		}
		return jLabelLaunchFeedback;
	}

	/**
	 * creates or gets the Send to Confluence checkbox    
	 */
	private JCheckBox getJCheckBoxSendToConfluence() {
		if (jCheckBoxSendToConfluence == null) {
			jCheckBoxSendToConfluence = new JCheckBox();
			jCheckBoxSendToConfluence.setFont(UWCLabel.getUWCFont());
			
			jCheckBoxSendToConfluence.setText(""); //No label - we'll add one somewhere else
			loadSetting(jCheckBoxSendToConfluence, Setting.SEND_TO_CONFLUENCE);
			jCheckBoxSendToConfluence.addItemListener(getSendPagesCheckboxListener());

			AbstractButton otherUiElement = getSendPagesCheckboxMenuItem();
			CheckboxObserver observer = new CheckboxObserver(
					this, otherUiElement, Setting.SEND_TO_CONFLUENCE);
			getSendPagesCheckboxListener().addObserver(observer);

			
		}
		return jCheckBoxSendToConfluence;
	}

	/**
	 * creates or gets the get feedback option checkbox    
	 */
	private JCheckBox getJCheckBoxFeedbackOption() {
		if (jCheckBoxFeedbackOption == null) {
			jCheckBoxFeedbackOption = new JCheckBox();
			jCheckBoxFeedbackOption.setFont(UWCLabel.getUWCFont());
			
			jCheckBoxFeedbackOption.setText(""); //No label - we'll add one somewhere else
			loadSetting(jCheckBoxFeedbackOption, Setting.FEEDBACK_OPTION);
			jCheckBoxFeedbackOption.addItemListener(getLaunchFeedbackCheckboxListener());
			
			AbstractButton otherUiElement = getLaunchFeedbackCheckBoxMenuItem();
			CheckboxObserver observer = new CheckboxObserver(
					this, otherUiElement, Setting.FEEDBACK_OPTION);
			getLaunchFeedbackCheckboxListener().addObserver(observer);

		}
		return jCheckBoxFeedbackOption;
	}
	/**
	 * creates or gets the test connection button    
	 */
	private JButton getJButtonTestConnection() {
		if (jButtonTestConnection == null) {
			jButtonTestConnection = new JButton();
			jButtonTestConnection.setFont(UWCLabel.getUWCFont());
			jButtonTestConnection.setText("Test Connection");
			//use this listener to get feedback about the test
			Vector<JTextField> testableSettingsObjects = getTestableSettingsObjects();
			testSettingsListener = new TestSettingsListener(testableSettingsObjects, this.model, this.getFeedbackWindow());
			jButtonTestConnection.addActionListener(testSettingsListener);
		}
		return jButtonTestConnection;
	}

	/**
	 * @return a vector of To Confluence textfields (address, login, pass, space)
	 */
	private Vector<JTextField> getTestableSettingsObjects() {
		Vector<JTextField> testables = new Vector<JTextField>();
		testables.add(getJTextfieldAddress());
		testables.add(getJTextFieldLogin());
		testables.add(getJPasswordField());
		testables.add(getJTextFieldSpace());
		return testables;
	}

	/**
	 * creates or gets the launch regex tester button    
	 */
	private JButton getJButtonLaunchRegexTester() {
		if (jButtonLaunchRegexTester == null) {
			jButtonLaunchRegexTester = new JButton();
			jButtonLaunchRegexTester.setFont(UWCLabel.getUWCFont());
			jButtonLaunchRegexTester.setText("Regex Tester");
			jButtonLaunchRegexTester.addActionListener(getRegexLauncher());
			
		}
		return jButtonLaunchRegexTester;
	}

	/**
	 * creates or gets the launch feedback button    
	 */
	private JButton getJButtonLaunchFeedback() {
		if (jButtonLaunchFeedback == null) {
			jButtonLaunchFeedback = new JButton();
			jButtonLaunchFeedback.setFont(UWCLabel.getUWCFont());
			jButtonLaunchFeedback.setText("Launch Feedback");
			jButtonLaunchFeedback.addActionListener(getLaunchFeedbackListener());
		}
		return jButtonLaunchFeedback;
	}
	
	/**
	 * creates or gets the feedback window.
	 */
	private FeedbackWindow getFeedbackWindow() {
		if (feedbackWindow == null) {
			feedbackWindow = new FeedbackWindow();
		}
		return feedbackWindow;
	}
	
	/**
	 * creates or gets the panel containing the convert and close buttons   
	 */
	private JPanel getJPanelMain() {
		if (jPanelMain == null) {
			jPanelMain = new JPanel();
			jPanelMain.setLayout(new FlowLayout(FlowLayout.RIGHT, 15, 5));
			jPanelMain.add(getJButtonConvert());
			jPanelMain.add(getJButtonClose());
		}
		return jPanelMain;
	}

	/**
	 * creates or gets the convert button    
	 */
	private JButton getJButtonConvert() {
		if (jButtonConvert == null) {
			jButtonConvert = new JButton();
			jButtonConvert.setFont(UWCLabel.getUWCFont());
			jButtonConvert.setText("Convert");
			jButtonConvert.addActionListener(
					new ConvertListener(jComboBox_WikiType, model, getPropsDir(), getFeedbackWindow()));
			jButtonConvert.setEnabled(hasSetAllConverterSettings());
		}
		return jButtonConvert;
	}

	/**
	 * @return true if all the conditions necessary to attempt conversion exist.
	 * Which wikitype, at least one page chosen, and all the To Confluence settings aren't empty  
	 */
	public boolean hasSetAllConverterSettings() {
		boolean hasWikitype = hasItem((String) getJComboBox_WikiType().getSelectedItem());
		boolean hasAddress = hasItem(getJTextfieldAddress().getText());
		boolean hasLogin = hasItem(getJTextFieldLogin().getText());
		boolean hasPass = getJPasswordField().getDocument().getLength() > 0; //doesn't respond to hasItem like textfield
		boolean hasSpace = hasItem(getJTextFieldSpace().getText());
		boolean hasOnePage = !model.getPageFiles().isEmpty();
		
		boolean hasSettings = hasWikitype && hasAddress && hasLogin && hasPass && hasSpace && hasOnePage;
		return hasSettings;
	}

	/**
	 * @param item
	 * @return true if given item represent an existing value
	 */
	private boolean hasItem(String item) {
		return (item != null && !"".equals(item));
	}

	/**
	 * creates or gets the close button    
	 */
	private JButton getJButtonClose() {
		if (jButtonClose == null) {
			jButtonClose = new JButton();
			jButtonClose.setFont(UWCLabel.getUWCFont());
			jButtonClose.setText("Close");
			jButtonClose.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					shutdownUWC();
				}
			});
			
		}
		return jButtonClose;
	}


	/* Listeners */
	
	/**
	 * creates or gets the listener which controls the add button's behavior.
	 * - handles launching the file dialog and choosing a page
	 * - handles notifying the remove button that it needs to check for enabled/disabled status
	 * - handles notifying the convert button that it needs to check for enabled/disabled status  
	 */
	private AddPagesListener getAddPagesListener() {
		if (this.addPagesListener == null ) {
			this.addPagesListener = new AddPagesListener(jScrollPanePages, model);
			//remove button's enabled state is dependant on whether there are currently pages or not
			this.addPagesListener.addObserver(getRemoveButtonEnabledListener());  
			//convert button's enabled state is dependant on whether there are currently pages or not
			this.addPagesListener.addObserver(getHasAllListener());
			this.addPagesListener.addObserver(new SaveListener(
					getJListPages(),
					this.model,
					Setting.PAGES,
					this.feedbackWindow
			));
		}
		return this.addPagesListener;
	}

	/**
	 * @return Observer which will check to see if the remove button should be enabled/disabled
	 */
	private Observer getRemoveButtonEnabledListener() {
		return (new Observer() {
			public void update(Observable o, Object arg) {
				UWCGuiModel model = getModel();
				boolean removeIsEnabled = !model.getPageFiles().isEmpty();
				getJButtonRemovePages().setEnabled(removeIsEnabled);
			}
		});
	}
	
	/**
	 * creates or gets the listener which controls the remove button's behavior.
	 * - handles remove chosen pages from the pages scrollpane
	 * - handles notifying the remove button that it needs to check for enabled/disabled status
	 * - handles notifying the convert button that it needs to check for enabled/disabled status  
	 */
	private RemovePagesListener getRemovePagesListener() {
		if (this.removePagesListener == null) {
			this.removePagesListener = new RemovePagesListener(jScrollPanePages, model);
			this.removePagesListener.addObserver(getHasAllListener());
			this.removePagesListener.addObserver(getRemoveButtonEnabledListener());
			this.removePagesListener.addObserver(new SaveListener(
					getJListPages(),
					this.model,
					Setting.PAGES,
					this.feedbackWindow
			));
		}
		return this.removePagesListener;
	}
	
	/**
	 * @return the listener that will enable/disable the given component based on
	 * the settings provided by the user
	 */
	private HasAllConvertSettingsListener getHasAllListener() {
		if (this.hasAllConvertSettingsListener == null) {
			this.hasAllConvertSettingsListener = new HasAllConvertSettingsListener(this);
			this.hasAllConvertSettingsListener.registerComponent(getJButtonConvert());
			this.hasAllConvertSettingsListener.registerComponent(getConvertMenuItem());
		}
		return this.hasAllConvertSettingsListener;
	}

	/**
	 * creates or gets the regex launcher listener.
	 * Calling the listener
	 * - launches the regex app    
	 */
	private ActionListener getRegexLauncher() {
		if (this.regexLauncher == null) {
			regexLauncher = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					jButtonLaunchRegexTester.setEnabled(false);
					AppRegexDemo demo = new AppRegexDemo(); 
					regexFrame = demo.getFrame();
					//so we can handle enabling it when the frame is closed
					regexFrame.setLaunchPoint(jButtonLaunchRegexTester);
				}
			};
		}
		return this.regexLauncher;
	}

	/**
	 * creates or gets the launch feedback listener. When called it:
	 * - launches the feedback window.
	 */
	private LaunchFeedbackListener getLaunchFeedbackListener() {
		if (this.launchFeedbackListener == null) {
			this.launchFeedbackListener = new LaunchFeedbackListener(getFeedbackWindow());
		}
		return this.launchFeedbackListener;
	}

	/* Layout Controls */

	/**
	 * creates a set of basic layout constraints used by
	 * practically all the swing objects
	 */
	private GridBagConstraints getBaseConstraints() {
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.insets = new Insets(BASE_INSET, BASE_INSET, BASE_INSET, BASE_INSET);
		return constraints;
	}

	/**
	 * creates a set of basic layout constraints used by 
	 * textfields
	 * Used in conjunction with GridBagLayout
	 * @param row 
	 * @return constraints for the given row
	 */
	private GridBagConstraints getBaseSettingsConstraints(int row) {
		GridBagConstraints constraints = getBaseConstraints();
		constraints.gridx = 1;
		constraints.gridy = row;
		constraints.gridwidth = 2;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		return constraints;
	}
	
	/**
	 * creates a set of layout constraints used by the connection settings textfields
	 * using the given row
	 * @param row
	 * @return
	 */
	private GridBagConstraints getToConfluenceTextfieldContraints(int row) {
		GridBagConstraints constraints = getBaseSettingsConstraints(row);
		constraints.gridwidth = 3;
		constraints.insets = new Insets(BASE_INSET, BASE_INSET, BASE_INSET, BASIC_RIGHT_MARGIN);
		return constraints;
	}

	/**
	 * creates a set of layout constraints with the given row,
	 * for the Header Labels like 
	 * 'Convert From Wiki'. 
	 * @param row
	 */
	private GridBagConstraints getHeaderLabelConstraints(int row) {
		GridBagConstraints constraints = getBaseConstraints();
		constraints.gridx = 0;
		constraints.gridy = row;
		constraints.gridwidth = 4;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.anchor = GridBagConstraints.PAGE_START;
		return constraints;
	}

	/**
	 * creates a set of layout constraints for the labels
	 * @param row
	 */
	private GridBagConstraints getBaseLabelConstraints(int row) {
		GridBagConstraints constraints = getBaseConstraints();
		constraints.gridx = 0;
		constraints.gridy = row;
		constraints.gridwidth = 1;
		constraints.anchor = GridBagConstraints.LINE_END; //right align
		constraints.insets = new Insets(BASE_INSET, LABEL_LEFT_MARGIN, BASE_INSET, LABEL_RIGHT_MARGIN);
		return constraints;
	}
	
	/**
	 * creates constraints for the ui on the advanced tab and
	 * on the given row
	 * @param row
	 * @return
	 */
	private GridBagConstraints getAdvancedButtonConstraints(int row) {
		GridBagConstraints constraints = getBaseConstraints();
		constraints.gridx = 0;
		constraints.gridy = row;
		constraints.anchor = GridBagConstraints.LINE_START; //left align
		int leftMargin = LABEL_LEFT_MARGIN - 10;
		int bottomMargin = BASE_INSET + 5;
		constraints.insets = new Insets(BASE_INSET, leftMargin, bottomMargin, LABEL_RIGHT_MARGIN);
		
		return constraints;
	}
	
	/**
	 * creates constraints for the labels on the advanced tab and on
	 * the given row
	 * @param row
	 * @return
	 */
	private GridBagConstraints getAdvancedLabelConstraints(int row) {
		GridBagConstraints constraints = getBaseConstraints();
		constraints.gridx = 1;
		constraints.gridy = row;
		constraints.anchor = GridBagConstraints.LINE_START; //left align
		return constraints;
	}
	
	/**
	 * creates a specialty constraint that should be used with the
	 * Attachment Size restriction label. The constraints will use the given row.
	 * @param row which row on the grid this label will be located
	 * @return
	 */
	private GridBagConstraints getAttachSizeLabelConstraints(int row) {
		GridBagConstraints constraints = getAdvancedLabelConstraints(row);
		
		//make the bottom of the label be just adjacent to the associated textfield
		constraints.insets.bottom = 0;
		
		return constraints;
	}
	
	/**
	 * creates a specialty constraint that should be used with the
	 * Attachment Size restriction textfield. The constraints will
	 * use the given row.
	 * @param row which row on the grid will be used
	 * @return
	 */
	private GridBagConstraints getAttachSizeTextFieldConstraints(int row) {
		GridBagConstraints constraints = getAdvancedLabelConstraints(row);
		// fix the width
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.insets.right = 160;  
		
		//make the top of the textfield be just adjacent to the associated label
		constraints.insets.top = 0;
		
		return constraints;
	}

	/**
	 * creates the basic constraints for the section headers
	 * that span the width of the app, with a default CENTER anchor
	 * @param column
	 * @param weight
	 * @return
	 */
	private GridBagConstraints getHeaderConstraintsByColumn(int column, double weight) {
		return getHeaderConstraintsByColumn(column, weight, GridBagConstraints.CENTER); 
	}

	/**
	 * creates the basic constraints for the section headers
	 * that span the width of the app
	 * @param column
	 * @param weight weightx for the component. 
	 * (handles how much space it gets as a column)
	 * @param anchor
	 * @return
	 */
	private GridBagConstraints getHeaderConstraintsByColumn(int column, double weight, int anchor) {
		GridBagConstraints constraints = getBaseConstraints();
		constraints.gridx = column;
		constraints.gridy = 0;
		constraints.anchor = anchor;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.weightx = weight;
		constraints.weighty = 0.0;
		constraints.insets = new Insets(0,0,0,0);
		return constraints;
	}

	/* Menu Getters */
	
	/**
	 * This method initializes converterMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getConverterMenu() {
		if (converterMenu == null) {
			converterMenu = new JMenu();
			converterMenu.setFont(UWCLabel.getUWCFont());
			converterMenu.setText("Convert");
			converterMenu.add(getConvertMenuItem());
			converterMenu.add(getExportMenuItem());
			addSeparator(converterMenu);
			converterMenu.add(getAddMenuItem());
			converterMenu.add(getRemoveMenuItem());
			addAccelerator(converterMenu, KeyEvent.VK_C);
		}
		return converterMenu;
	}

	/**
	 * This method initializes View	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getView() {
		if (viewMenu == null) {
			viewMenu = new JMenu();
			viewMenu.setFont(UWCLabel.getUWCFont());
			viewMenu.setText("View");
			viewMenu.add(getConversionSettingMenuItem());
			viewMenu.add(getOtherToolsTabMenuItem());
			addAccelerator(viewMenu, KeyEvent.VK_V);
		}
		return viewMenu;
	}

	/**
	 * This method initializes toolsMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getToolsMenu() {
		if (toolsMenu == null) {
			toolsMenu = new JMenu();
			toolsMenu.setFont(UWCLabel.getUWCFont());
			toolsMenu.setText("Tools");
			toolsMenu.add(getWhenConvertingMenu());
			addSeparator(toolsMenu);
			toolsMenu.add(getTestConnectionMenuItem());
			toolsMenu.add(getRegexTesterMenuItem());
			toolsMenu.add(getLaunchFeedbackMenuItem());
			addAccelerator(toolsMenu, KeyEvent.VK_T);
		}
		return toolsMenu;
	}

	/**
	 * This method initializes convertMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getConvertMenuItem() {
		if (convertMenuItem == null) {
			convertMenuItem = new JMenuItem();
			convertMenuItem.setFont(UWCLabel.getUWCFont());
			convertMenuItem.setText("Convert");
			addAccelerator(convertMenuItem, KeyEvent.VK_C, getShiftAccelerator());
			convertMenuItem.setPreferredSize(getIncreasedHeight(convertMenuItem));
			convertMenuItem.addActionListener(
					new ConvertListener(jComboBox_WikiType, model, getPropsDir(), getFeedbackWindow()));
			convertMenuItem.setEnabled(hasSetAllConverterSettings()); 
			
		}
		return convertMenuItem;
	}

	/**
	 * This method initializes exportMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getExportMenuItem() {
		if (exportMenuItem == null) {
			exportMenuItem = new JMenuItem();
			exportMenuItem.setFont(UWCLabel.getUWCFont());
			exportMenuItem.setText("Export");
			addAccelerator(exportMenuItem, KeyEvent.VK_E, getOsAccelerator());
			exportMenuItem.setPreferredSize(getIncreasedHeight(exportMenuItem));
			exportMenuItem.setEnabled(false); //only available when appropriate wiki is being used
			exportMenuItem.addActionListener(
					new ExportWikiListener(
							jComboBox_WikiType,
							this.model,
							getPropsDir(),
							getFeedbackWindow()));
		}
		return exportMenuItem;
	}

	/**
	 * This method initializes addMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getAddMenuItem() {
		if (addMenuItem == null) {
			addMenuItem = new JMenuItem();
			addMenuItem.setFont(UWCLabel.getUWCFont());
			addMenuItem.setText("Add Pages");
			addAccelerator(addMenuItem, KeyEvent.VK_A, getOsAccelerator());
			addMenuItem.setPreferredSize(getIncreasedHeight(addMenuItem));
			addMenuItem.addActionListener(getAddPagesListener());
		}
		return addMenuItem;
	}

	/**
	 * This method initializes removeMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getRemoveMenuItem() {
		if (removeMenuItem == null) {
			removeMenuItem = new JMenuItem();
			removeMenuItem.setFont(UWCLabel.getUWCFont());
			removeMenuItem.setText("Remove Pages");
			addAccelerator(removeMenuItem, KeyEvent.VK_R, getOsAccelerator());
			removeMenuItem.setPreferredSize(getIncreasedHeight(removeMenuItem));
			removeMenuItem.addActionListener(getRemovePagesListener());
		}
		return removeMenuItem;
	}

	/**
	 * This method initializes conversionSettingMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getConversionSettingMenuItem() {
		if (conversionTabMenuItem == null) {
			conversionTabMenuItem = new JMenuItem();
			conversionTabMenuItem.setFont(UWCLabel.getUWCFont());
			conversionTabMenuItem.setText("Conversion Settings");
			addAccelerator(conversionTabMenuItem, KeyEvent.VK_1, getOsAccelerator());
			conversionTabMenuItem.setPreferredSize(getIncreasedHeight(removeMenuItem));
			conversionTabMenuItem.setPreferredSize(getIncreasedWidth(removeMenuItem, 40));
			conversionTabMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JTabbedPane tabs = getJTabbedPane();
					JPanel conTab = getJPanelBasic();
					tabs.setSelectedComponent(conTab);
				}
			});
		}
		return conversionTabMenuItem;
	}

	/**
	 * This method initializes otherToolsTabMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getOtherToolsTabMenuItem() {
		if (otherToolsTabMenuItem == null) {
			otherToolsTabMenuItem = new JMenuItem();
			otherToolsTabMenuItem.setFont(UWCLabel.getUWCFont());
			otherToolsTabMenuItem.setText("Other Tools");
			addAccelerator(otherToolsTabMenuItem, KeyEvent.VK_2, getOsAccelerator());
			otherToolsTabMenuItem.setPreferredSize(getIncreasedHeight(otherToolsTabMenuItem));
		}
		otherToolsTabMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JTabbedPane tabs = getJTabbedPane();
				JPanel otherTab = getJPanelAdvanced();
				tabs.setSelectedComponent(otherTab);
			}
		});
		return otherToolsTabMenuItem;
	}

	/**
	 * This method initializes sendPagesMenuItem	
	 * 	
	 * @return javax.swing.JCheckBoxMenuItem	
	 */
	private JCheckBoxMenuItem getSendPagesCheckboxMenuItem() {
		if (sendPagesCheckboxMenuItem == null) {
			sendPagesCheckboxMenuItem = new JCheckBoxMenuItem();
			sendPagesCheckboxMenuItem.setFont(UWCLabel.getUWCFont());
			sendPagesCheckboxMenuItem.setText("Send Pages");
			sendPagesCheckboxMenuItem.setPreferredSize(getIncreasedHeight(sendPagesCheckboxMenuItem));

			loadSetting(sendPagesCheckboxMenuItem, Setting.SEND_TO_CONFLUENCE);
			
			sendPagesCheckboxMenuItem.addItemListener(getSendPagesCheckboxListener());

			JCheckBox otherUiElement = getJCheckBoxSendToConfluence();
			CheckboxObserver observer = new CheckboxObserver(
					this, otherUiElement, Setting.SEND_TO_CONFLUENCE);
			getSendPagesCheckboxListener().addObserver(observer);
			
		}
		return sendPagesCheckboxMenuItem;
	}

	/**
	 * This method initializes attachmentSizeCheckboxMenuItem
	 * @return javaz.swing.JCheckBoxMenuItem
	 */
	private JCheckBoxMenuItem getAttachmentSizeCheckBoxMenuItem() {
		if (attachmentSizeCheckboxMenuItem == null) {
			attachmentSizeCheckboxMenuItem = new JCheckBoxMenuItem();
			attachmentSizeCheckboxMenuItem.setFont(UWCLabel.getUWCFont());
			attachmentSizeCheckboxMenuItem.setText("Restrict Attachment Size");
			attachmentSizeCheckboxMenuItem.setPreferredSize(getIncreasedHeight(attachmentSizeCheckboxMenuItem));

			attachmentSizeCheckboxMenuItem.setSelected(getBooleanSettingFromString(Setting.ATTACHMENT_SIZE, UWCUserSettings.DEFAULT_ATTACHMENT_SIZE));
			
			attachmentSizeCheckboxMenuItem.addItemListener(getAttachmentSizeMenuItemListener()); //FILE_ATTACH_Z1

			JCheckBox otherUiElement = getJCheckBoxAttachmentSize(); //FILE_ATTACH_Z1
			CheckboxObserver observer = new CheckboxObserver(
					this, otherUiElement, Setting.ATTACHMENT_SIZE);
			getAttachmentSizeMenuItemListener().addObserver(observer); //FILE_ATTACH_Z1
			
			
		}
		return attachmentSizeCheckboxMenuItem;

	}
	
	/**
	 * loads selectable with the boolean value associated with the setting
	 * as it is currently represented in the model
	 * @param selectable
	 * @param setting
	 */
	public void loadSetting(AbstractButton selectable, Setting setting) {
		boolean settingBool = Boolean.parseBoolean(this.model.getSetting(setting));
		selectable.setSelected(settingBool);
	}
	
	/**
	 * loads the given ui element with the boolean based on the value for the given setting 
	 * and given defaultValue.
	 * @param element ui element to be loaded with a boolean value
	 * @param setting the key representing the current setting
	 * @param defaultValue default value for the setting 
	 */
	public void loadBooleanSettingFromString(AbstractButton element, Setting setting, String defaultValue) {
		boolean booleanSettingFromString = getBooleanSettingFromString(setting, defaultValue);
		element.setSelected(booleanSettingFromString);
	}
	
	/**
	 * @param setting key representing which setting is being examined
	 * @param defaultValue default value for this setting
	 * @return true if the model value for the given setting is not the default value
	 */
	public boolean getBooleanSettingFromString(Setting setting, String defaultValue ) {
		String intString = this.model.getSetting(setting);
		return (defaultValue.equals(intString))?false:true;
	}

	/**
	 * @return gets or creates the sendPagesCheckboxListener
	 */
	private ChangeCheckboxListener getSendPagesCheckboxListener() {
		if (this.sendPagesCheckboxListener == null)
			this.sendPagesCheckboxListener = new ChangeCheckboxListener(this.model, Setting.SEND_TO_CONFLUENCE);
		return this.sendPagesCheckboxListener;
	}

	/**
	 * @return gets or returns the attachmentSizeCheckboxListener
	 */
	private ChangeCheckboxListener getAttachmentSizeCheckboxListener() {
		if (this.attachmentSizeCheckboxListener == null)
			this.attachmentSizeCheckboxListener = new ChangeAttachmentCheckboxListener(this.model, Setting.ATTACHMENT_SIZE, getJTextFieldAttachmentSize());
		return this.attachmentSizeCheckboxListener;
	}

	/**
	 * @return gets or creates the attachmentSizeMenuItemListener
	 */
	private ChangeCheckboxListener getAttachmentSizeMenuItemListener() { 
		if (this.attachmentSizeMenuItemListener == null)
			this.attachmentSizeMenuItemListener = new ChangeAttachmentCheckboxListener(this.model, Setting.ATTACHMENT_SIZE, getJTextFieldAttachmentSize());
		return this.attachmentSizeMenuItemListener;
	}

	/**
	 * This method initializes launchFeedbackCheckBoxMenuItem	
	 * 	
	 * @return javax.swing.JCheckBoxMenuItem	
	 */
	private JCheckBoxMenuItem getLaunchFeedbackCheckBoxMenuItem() {
		if (launchFeedbackCheckboxMenuItem == null) {
			launchFeedbackCheckboxMenuItem = new JCheckBoxMenuItem();
			launchFeedbackCheckboxMenuItem.setFont(UWCLabel.getUWCFont());
			launchFeedbackCheckboxMenuItem.setText("Launch Feedback");
			launchFeedbackCheckboxMenuItem.setPreferredSize(getIncreasedHeight(launchFeedbackCheckboxMenuItem));
			loadSetting(launchFeedbackCheckboxMenuItem, Setting.FEEDBACK_OPTION);
			launchFeedbackCheckboxMenuItem.addItemListener(getLaunchFeedbackCheckboxListener());
			
			AbstractButton otherUiElement = getJCheckBoxFeedbackOption();
			CheckboxObserver observer = new CheckboxObserver(
					this, otherUiElement, Setting.FEEDBACK_OPTION);
			getLaunchFeedbackCheckboxListener().addObserver(observer);

		}
		return launchFeedbackCheckboxMenuItem;
	}

	/**
	 * @return gets or creates launchFeedbackCheckboxListener
	 */
	private ChangeCheckboxListener getLaunchFeedbackCheckboxListener() {
		if (this.launchFeedbackCheckboxListener == null)
			this.launchFeedbackCheckboxListener = new ChangeCheckboxListener(this.model, Setting.FEEDBACK_OPTION);
		return this.launchFeedbackCheckboxListener;
	}

	/**
	 * This method initializes testConnectionMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getTestConnectionMenuItem() {
		if (testConnectionMenuItem == null) {
			testConnectionMenuItem = new JMenuItem();
			testConnectionMenuItem.setFont(UWCLabel.getUWCFont());
			testConnectionMenuItem.setText("Test Connection");
			testConnectionMenuItem.setPreferredSize(getIncreasedHeight(testConnectionMenuItem));			
			testConnectionMenuItem.addActionListener(testSettingsListener);
			addAccelerator(testConnectionMenuItem, KeyEvent.VK_T, getOsAccelerator());
		}
		return testConnectionMenuItem;
	}

	/**
	 * This method initializes regexTesterMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getRegexTesterMenuItem() {
		if (regexTesterMenuItem == null) {
			regexTesterMenuItem = new JMenuItem();
			regexTesterMenuItem.setFont(UWCLabel.getUWCFont());
			regexTesterMenuItem.setText("Regex Tester");
			regexTesterMenuItem.setPreferredSize(getIncreasedHeight(regexTesterMenuItem));
			regexTesterMenuItem.addActionListener(getRegexLauncher());
		}
		return regexTesterMenuItem;
	}

	/**
	 * This method initializes launchFeedbackMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getLaunchFeedbackMenuItem() {
		if (launchFeedbackMenuItem == null) {
			launchFeedbackMenuItem = new JMenuItem();
			launchFeedbackMenuItem.setFont(UWCLabel.getUWCFont());
			launchFeedbackMenuItem.setText("Feedback Window");
			launchFeedbackMenuItem.setPreferredSize(getIncreasedHeight(launchFeedbackMenuItem));
			launchFeedbackMenuItem.setPreferredSize(getIncreasedWidth(launchFeedbackMenuItem, 40));
			launchFeedbackMenuItem.addActionListener(getLaunchFeedbackListener());
			addAccelerator(launchFeedbackMenuItem, KeyEvent.VK_F, getOsAccelerator());
		}
		return launchFeedbackMenuItem;
	}

	/**
	 * This method initializes whenConvertingMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getWhenConvertingMenu() {
		if (whenConvertingMenu == null) {
			whenConvertingMenu = new JMenu();
			whenConvertingMenu.setFont(UWCLabel.getUWCFont());
			whenConvertingMenu.setText("When Converting...");
			whenConvertingMenu.add(getSendPagesCheckboxMenuItem());
			whenConvertingMenu.add(getLaunchFeedbackCheckBoxMenuItem());
			whenConvertingMenu.add(getAttachmentSizeCheckBoxMenuItem());
			whenConvertingMenu.setPreferredSize(getIncreasedHeight(whenConvertingMenu));
		}
		return whenConvertingMenu;
	}

	/**
	 * This method initializes onlineDocMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getOnlineDocMenu() {
		if (onlineDocMenu == null) {
			onlineDocMenu = new JMenu();
			onlineDocMenu.setFont(UWCLabel.getUWCFont());
			onlineDocMenu.setText("Online Doc");
			onlineDocMenu.add(getUwcMainDoc());
			onlineDocMenu.add(getUwcGuiDoc());
			onlineDocMenu.add(getQuickDoc());
			onlineDocMenu.add(getSSLDoc());
			onlineDocMenu.setPreferredSize(getIncreasedHeight(onlineDocMenu));
			onlineDocMenu.setMnemonic(KeyEvent.VK_O);

			addSeparator(onlineDocMenu);

			//wiki specific doc pages
			Vector<String> wikitypes = model.getWikiTypesList(getPropsDir());
			for (String wikitype : wikitypes) { 
				//ignore known test files
				if (wikitype.equals("test") ||
						wikitype.equals("testHierarchy") ||
						wikitype.equals("NoSyntaxConversions") ||
						wikitype.equals("moinmoini"))
					continue;
				//add a menu item pointed at doc page for that wiki type
				JMenuItem item = getWikitypeDocMenuItem(wikitype);
				if (item != null) onlineDocMenu.add(item);
			}
		}
		return onlineDocMenu;
	}

	/**
	 * This method initializes uwcMainDoc	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getUwcMainDoc() {
		if (uwcMainDoc == null) {
			uwcMainDoc = new JMenuItem();
			uwcMainDoc.setFont(UWCLabel.getUWCFont());
			uwcMainDoc.setText("UWC Doc");
			uwcMainDoc.setPreferredSize(getIncreasedHeight(uwcMainDoc));
			uwcMainDoc.setMnemonic(KeyEvent.VK_U);
			String link = UWC_DOC_WEBSITE;
			uwcMainDoc.addActionListener(new UrlLauncher(link, this.feedbackWindow));
		}
		return uwcMainDoc;
	}

	/**
	 * This method initializes quickDoc	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getQuickDoc() {
		if (quickDoc == null) {
			quickDoc = new JMenuItem();
			quickDoc.setFont(UWCLabel.getUWCFont());
			quickDoc.setText("Quick Start Guide");
			quickDoc.setPreferredSize(getIncreasedHeight(quickDoc));
			quickDoc.setMnemonic(KeyEvent.VK_Q);
			String link = UWC_DOC_URL + "UWC+Quick+Start";
			quickDoc.addActionListener(new UrlLauncher(link, this.feedbackWindow));
		}
		return quickDoc;
	}
	
	/**
	 * This method initializes sslDoc	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getSSLDoc() {
		if (sslDoc == null) {
			sslDoc = new JMenuItem();
			sslDoc.setFont(UWCLabel.getUWCFont());
			sslDoc.setText("SSL Support");
			sslDoc.setPreferredSize(getIncreasedHeight(sslDoc));
			String link = UWC_DOC_URL + "UWC+SSL+Support";
			sslDoc.addActionListener(new UrlLauncher(link, this.feedbackWindow));
		}
		return sslDoc;
	}
	
	/**
	 * @return creates or gets guiDoc
	 */
	private JMenuItem getUwcGuiDoc() {
		if (this.guiDoc == null) {
			guiDoc = new JMenuItem();
			guiDoc.setFont(UWCLabel.getUWCFont());
			guiDoc.setText("New UI Doc");
			guiDoc.setPreferredSize(getIncreasedHeight(guiDoc));
			guiDoc.setMnemonic(KeyEvent.VK_N);
			String link = UWC_DOC_URL + "UWC+GUI+v3+Documentation";
			guiDoc.addActionListener(new UrlLauncher(link, this.feedbackWindow));
		}
		return guiDoc;
	}
	
	/**
	 * creates or gets a menu item for a particular wikitype's doc
	 * @param wikitype
	 * @return menu item linked to the wiki specific doc
	 * for the given wikitype
	 */
	private JMenuItem getWikitypeDocMenuItem(String wikitype) {
		getWikiHelpMenuItems(); //if object is undefined, will define it.
		if (this.wikiHelpMenuItems.containsKey(wikitype)) //return the existing one
			return this.wikiHelpMenuItems.get(wikitype);
		JMenuItem item = createJMenuItem(wikitype); //or if doesn't exist, create it
		if (item == null) return null;
		this.wikiHelpMenuItems.put(wikitype, item);
		return item;
	}
	
	/**
	 * @return gets or creates wikiHelpMenuItems
	 */
	private HashMap<String,JMenuItem> getWikiHelpMenuItems() {
		if (this.wikiHelpMenuItems == null)
			this.wikiHelpMenuItems = new HashMap<String,JMenuItem>();
		return this.wikiHelpMenuItems;
	}

	/**
	 * @param wikitype
	 * @return a new menu item corresponding to the given wikitype, 
	 * and linked to that wikitype's doc site
	 */
	private JMenuItem createJMenuItem(String wikitype) {
		JMenuItem item = new JMenuItem();
		item.setFont(UWCLabel.getUWCFont());
		item.setText(getFirstCharUpperCase(wikitype) + " Doc"); 
		item.setPreferredSize(getIncreasedHeight(item));
		int mnemonic = getAvailableMnemonic(wikitype);
		if (mnemonic > -1) //only set mnemonic if an appropriate one was found
			item.setMnemonic(mnemonic);
		String link = getWikiDocLink(wikitype);
		if (link == null) return null;
		item.addActionListener(new UrlLauncher(link, this.feedbackWindow));
		return item;
	}

	/**
	 * transforms the given input to have the first letter be upper case
	 * @param input
	 * @return transformed string
	 */
	protected String getFirstCharUpperCase(String input) {
		String first = input.substring(0,1);
		String last = input.substring(1);
		first = first.toUpperCase();
		return first + last;
	}

	/**
	 * chooses an appropriate character based on the given input
	 * @param input
	 * @return an acceptable int value for a character from the given input
	 * that can be used as a mnemonic. character must be from given word, and
	 * must not be already in use with this set. if cannot find one, returns -1;
	 */
	protected int getAvailableMnemonic(String input) {
		Vector<Integer> available = this.availableWikiHelpDocMnemonics;
		if (available == null) { //create it if it doesn't exist
			available = new Vector<Integer>();
			//add already existing Mnemonics
			available.add((int)"U".toCharArray()[0]); //uwc doc
			available.add((int)"Q".toCharArray()[0]); //quick start
		}
		input = input.toUpperCase(); //keyevents are associated with upper case chars
		for (int i = 0; i < input.length(); i++) { 	//foreach character in the word
			char c = input.charAt(i);
			int charAsInt = (int) c ;					
			if (available.contains(charAsInt)) {		//char already in use. choose another one.
				continue;
			}
			available.add(charAsInt);					//found a char. add it to the vector.
			this.availableWikiHelpDocMnemonics = available;
			return charAsInt;
		}
		return -1;										//give up. can't find suitable unused char.
	}

	Pattern nodocwiki = Pattern.compile("(test)|(-)");
	/**
	 * builds the url for the given wikitype's doc
	 * @param wikitype
	 * @return url
	 */
	protected String getWikiDocLink(String wikitype) { 
		//hide wikitypes that have the word "test" or a "-"
		Matcher nodocFinder = nodocwiki.matcher(wikitype);
		if (nodocFinder.find()) return null;
		//create link
		String link = 
				UWC_DOC_URL +
				"UWC" +
				"+" +
				wikitype +
				"+" +
				"Notes";
		return link;
	}
	
	/**
	 * This method initializes jJMenuBar	
	 * 	
	 * @return javax.swing.JMenuBar	
	 */
	private JMenuBar getJJMenuBar() {
		if (jJMenuBar == null) {
			jJMenuBar = new JMenuBar();
			jJMenuBar.add(getFileMenu());
			jJMenuBar.add(getConverterMenu());
			jJMenuBar.add(getView());
			jJMenuBar.add(getToolsMenu());
			jJMenuBar.add(getHelpMenu());
		}
		return jJMenuBar;
	}

	/**
	 * This method initializes jMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getFileMenu() {
		if (fileMenu == null) {
			fileMenu = new JMenu();
			fileMenu.setFont(UWCLabel.getUWCFont());
			fileMenu.setText("File");
			fileMenu.add(getSaveMenuItem());
			fileMenu.add(getExitMenuItem());
			addAccelerator(fileMenu, KeyEvent.VK_F);
		}
		return fileMenu;
	}

	/**
	 * @return text for the close button/menu item.
	 * Should reflect user's OS
	 */
	private String getCloseText() {
		boolean isMac = isMac();
		if (isMac)
			return "Quit";
		return "Close";
	}
	
	/**
	 * @return keyboard accel key for the close menu item.
	 * Should reflect user's OS (X for Win, Q for Mac, etc.)
	 */
	private int getCloseKey() {
		if (isMac())
			return KeyEvent.VK_Q;
		return KeyEvent.VK_X;
	}

	/**
	 * @return true if the system env variable os.name 
	 * indicates the system is a mac
	 */
	private boolean isMac() {
		String os = System.getProperty("os.name");
		String osRegex = 	"(?i)" +	//case insensitive
							"mac"; 		//the string: "mac"
		return Pattern.compile(osRegex).matcher(os).find(); 
	}

	/**
	 * This method initializes jMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getHelpMenu() {
		if (helpMenu == null) {
			helpMenu = new JMenu();
			helpMenu.setFont(UWCLabel.getUWCFont());
			helpMenu.setText("Help");
			helpMenu.add(getOnlineDocMenu());
			helpMenu.add(getAboutMenuItem());
			addAccelerator(helpMenu, KeyEvent.VK_H);
		}
		return helpMenu;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getExitMenuItem() {
		if (exitMenuItem == null) {
			exitMenuItem = new JMenuItem();
			exitMenuItem.setFont(UWCLabel.getUWCFont());
			exitMenuItem.setText(getCloseText());
			exitMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					shutdownUWC();
				}

			});
			addAccelerator(exitMenuItem, getCloseKey(), getOsAccelerator()); 
			exitMenuItem.setPreferredSize(getIncreasedHeight(exitMenuItem));	
		}
		return exitMenuItem;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getAboutMenuItem() {
		if (aboutMenuItem == null) {
			aboutMenuItem = new JMenuItem();
			aboutMenuItem.setFont(UWCLabel.getUWCFont());
			aboutMenuItem.setText("About");
			aboutMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JFrame aboutDialog = getAboutDialog();
					aboutDialog.setVisible(true);
				}
			});
			aboutMenuItem.setPreferredSize(getIncreasedHeight(aboutMenuItem));
			aboutMenuItem.setMnemonic(KeyEvent.VK_A);
		}
		return aboutMenuItem;
	}

	/**
	 * This method initializes aboutDialog	
	 * 	
	 * @return javax.swing.JDialog
	 */
	protected JFrame getAboutDialog() {
		if (aboutDialog == null) {
			aboutDialog = new SupportWindow("About " + APP_NAME);
		}
		return aboutDialog;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getSaveMenuItem() {
		if (saveMenuItem == null) {
			saveMenuItem = new JMenuItem();
			saveMenuItem.setFont(UWCLabel.getUWCFont());
			saveMenuItem.setText("Save");
			addAccelerator(saveMenuItem, KeyEvent.VK_S, getOsAccelerator());
			saveMenuItem.setPreferredSize(getIncreasedHeight(saveMenuItem));
			
			saveMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					save(); 
				}
			});
		}
		return saveMenuItem;
	}

	/**
	 * calculates an increased height for the given item
	 * @param item
	 * @return Dimension representing an increased height for the given item
	 */
	private Dimension getIncreasedHeight(JComponent item) {
		return getIncreasedHeight(item, 6);
	}

	/**
	 * calculates an increased height for the given item, with the given increase amount
	 * @param item
	 * @param increase
	 * @return Dimension representing an increased height for the given item
	 */
	private Dimension getIncreasedHeight(JComponent item, int increase) {
		Dimension size = item.getPreferredSize();
		size.height += increase;
		return size;
	}
	
	/**
	 * calculates an increased width for the given item with the given increase amount
	 * @param item
	 * @param increase
	 * @return Dimension representing an increased width for the given item
	 */
	private Dimension getIncreasedWidth(JComponent item, int increase) {
		Dimension size = item.getPreferredSize();
		size.width += increase;
		return size;
	}

	/**
	 * @return the correct accelerator mask for the system.
	 * For example: Command for Macs, Control for Windows, etc.
	 */
	public static int getOsAccelerator() {
		return Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
	}
	
	/**
	 * @return Shift Mask + correct accelerator for the system.
	 * For example: Shift-Command for Macs
	 */
	private int getShiftAccelerator() {
		int osAccel = getOsAccelerator();
		return InputEvent.SHIFT_MASK | osAccel;
	}
	
	/**
	 * sets the given item's accelerator with the given key, and the given accelerator key
	 * @param item menu item which is getting the accelerator set
	 * @param key KeyEvent constant representing a key, Example: KeyEvent.VK_A
	 * @param accelerator KeyEvent constant representing a combo key. Example: InputEvent.CTRL_MASK
	 */
	public static void addAccelerator(JMenuItem item, int key, int accelerator) {
		item.setAccelerator(KeyStroke.getKeyStroke(key, accelerator, true));
	}
	
	/**
	 * sets the given menu's mnemonic with the given key
	 * @param menu menu item which is getting the mnemonic set
	 * @param key KeyEvent constant representing a key, Example: KeyEvent.VK_S
	 */
	private void addAccelerator(JMenu menu, int key) {
		menu.setMnemonic(key);
	}
	
	/**
	 * adds a separator to the given menu.
	 * @param menu
	 */
	public void addSeparator(JMenu menu) {
		JSeparator separator = new JSeparator(SwingConstants.HORIZONTAL);
		separator.setForeground(new Color(200, 200, 200)); //224
		separator.setPreferredSize(getIncreasedHeight(separator, -1));
		menu.add(separator);
	}
	
	/**
	 * This method initializes jCheckBoxAttachmentSize	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJCheckBoxAttachmentSize() {
		if (jCheckBoxAttachmentSize == null) {
			jCheckBoxAttachmentSize = new JCheckBox();
			jCheckBoxAttachmentSize.setFont(UWCLabel.getUWCFont());
			
			jCheckBoxAttachmentSize.setText(""); //No label - we'll add one somewhere else
			jCheckBoxAttachmentSize.setSelected(getBooleanSettingFromString(Setting.ATTACHMENT_SIZE, UWCUserSettings.DEFAULT_ATTACHMENT_SIZE));
			
			jCheckBoxAttachmentSize.addItemListener(getAttachmentSizeCheckboxListener());
			
			Observer enableTextFieldObserver = getEnableTextFieldObserver(getJTextFieldAttachmentSize());
			getAttachmentSizeCheckboxListener().addObserver(enableTextFieldObserver);
			
			AbstractButton otherUiElement = getAttachmentSizeCheckBoxMenuItem();
			CheckboxObserver observer = new CheckboxObserver(
					this, otherUiElement, Setting.ATTACHMENT_SIZE);
			getAttachmentSizeCheckboxListener().addObserver(observer);

		}
		return jCheckBoxAttachmentSize;
	}

	/**
	 * @param textfield
	 * @return new EnableTextFieldObserver instantiated with the given textfield
	 */
	private Observer getEnableTextFieldObserver(JTextField textfield) {
		EnableTextFieldObserver observer = new EnableTextFieldObserver(textfield);
		return observer;
	}

	/**
	 * This method initializes jTextFieldAttachmentSize	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJTextFieldAttachmentSize() {
		if (jTextFieldAttachmentSize == null) {
			jTextFieldAttachmentSize = new JTextField();
			jTextFieldAttachmentSize.setFont(UWCLabel.getUWCFont());
			SaveListener saveListener = new SaveListener(
					this.jTextFieldAttachmentSize, 
					this.model, 
					Setting.ATTACHMENT_SIZE,
					this.feedbackWindow
			);
			jTextFieldAttachmentSize.addActionListener(saveListener);
			jTextFieldAttachmentSize.addFocusListener(saveListener);
			jTextFieldAttachmentSize.addKeyListener(new IgnoreAltListener(jTextFieldAttachmentSize));
			
			jTextFieldAttachmentSize.setText(this.model.getSetting(Setting.ATTACHMENT_SIZE));
			jTextFieldAttachmentSize.setEnabled(getBooleanSettingFromString(Setting.ATTACHMENT_SIZE, UWCUserSettings.DEFAULT_ATTACHMENT_SIZE));
		}
		return jTextFieldAttachmentSize;
	}

	/* General Methods */
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length > 0) setPropsDir(args[0]); //useful for testing
		
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				UWCForm3 application = new UWCForm3();
				application.getJFrame().setVisible(true);
			}
		});
	}

	/**
	 * sets the properties directory with the given value.
	 * All proeprties loading will use this value unless it's null
	 * @param value directory containing properties
	 */
	private static void setPropsDir(String value) {
		commandLineArgDir = value;
	}

	/**
	 * any necessary init code that isn't handled by getJFrame
	 */
	private void init() {
		//init the logging
		PropertyConfigurator.configure("log4j.properties");
		//init the model
		model = new UWCGuiModel();
		//setup shutdown hooks, important for OS-initiated shutdowns
		Runtime.getRuntime().addShutdownHook(new Thread(new ShutDownController(this)));
	}

	/**
	 * This method initializes jFrame
	 * 
	 * @return javax.swing.JFrame
	 */
	protected JFrame getJFrame() {
		if (jFrame == null) {
			init();
			jFrame = new JFrame();
			jFrame.setSize(450, 640);
			jFrame.setLocation(20, 0); //not quite flush with the left edge of the screen
			jFrame.setContentPane(getJContentPane());
			jFrame.setTitle(getAppTitle());
			// can't use default close op, 'cause we need to save before closing
			// jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			// so instead we do this:
			jFrame.addWindowListener(new java.awt.event.WindowAdapter() {
				public void windowClosing(java.awt.event.WindowEvent e) {
					shutdownUWC();
				}
			});
			jFrame.setJMenuBar(getJJMenuBar()); //this has to be last, as necessary objects are defined earlier
		}
		return jFrame;
	}

	/**
	 * @return UWC's official name as displayed on the UI, includes version number
	 */
	private String getAppTitle() {
		String title = APP_NAME;
		title += " " + VERSION_INDICATOR + VERSION_NUMBER;
		return title;
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJTabbedPane(), BorderLayout.NORTH); 
			jContentPane.add(getJPanelMain(), BorderLayout.EAST);
		}
		return jContentPane;
	}

	/* Convenience Methods */

	/**
	 * convenience method for setting a colored border for
	 * a particular component. Useful for layout development.
	 * @param obj
	 * @param color
	 */
	private void setBorder(JComponent obj, Color color) {
		obj.setBorder(new LineBorder(color));		
	}
	
	/**
	 * @return Map of conversion setting components.
	 * Keys are:
	 * attachmentsText
	 * attachmentsButton
	 * pages
	 * add
	 * remove
	 * addMenu
	 * removeMenu
	 * address
	 * login
	 * password
	 * space
	 */
	public HashMap<String, Component> getConversionSettingsComponents() {
		HashMap<String, Component> components = new HashMap<String, Component>();
		components.put("attachmentsText", getJTextFieldAttachments());
		components.put("attachmentsButton", getJButtonAttachments());
		components.put("pages", getJScrollPanePages());
		components.put("add", getJButtonAdd());
		components.put("remove", getJButtonRemovePages());
		components.put("addMenu", getAddMenuItem());
		components.put("removeMenu", getRemoveMenuItem());
		components.put("address", getJTextfieldAddress());
		components.put("login", getJTextFieldLogin());
		components.put("password", getJPasswordField());
		components.put("space", getJTextFieldSpace());
		return components;
	}
	
	/* Inner Classes */
	
	/**
	 * handles any tasks that need to be done before shutdown
	 */
	private class ShutDownController implements Runnable {
		
		private UWCForm3 form;
		public ShutDownController(UWCForm3 form) {
			this.form = form;
		}
		public void run() {
			this.form.preShutdownCleanup();
		}
		
	}
}

