/*
 * org.openmicroscopy.shoola.util.ui.MessengerDialog 
 *
 *------------------------------------------------------------------------------
 *  Copyright (C) 2006 University of Dundee. All rights reserved.
 *
 *
 * 	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.
 *  
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *------------------------------------------------------------------------------
 */
package org.openmicroscopy.shoola.util.ui;



//Java imports
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyledDocument;


//Third-party libraries
import org.jdesktop.swingx.JXBusyLabel;
import info.clearthought.layout.TableLayout;
import org.apache.commons.collections.CollectionUtils;

//Application-internal dependencies
import org.openmicroscopy.shoola.util.file.ImportErrorObject;

/** 
 * A dialog used to collect and send comments or error messages.
 *
 * @author  Jean-Marie Burel &nbsp;&nbsp;&nbsp;&nbsp;
 * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
 * @author Donald MacDonald &nbsp;&nbsp;&nbsp;&nbsp;
 * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a>
 * after code from 
 * @author Brian Loranger &nbsp;&nbsp;&nbsp;&nbsp;
 * <a href="mailto:brian.loranger@lifesci.dundee.ac.uk">
 * brian.loranger@lifesci.dundee.ac.uk</a>
 * 
 * @version 3.0
 * <small>
 * (<b>Internal version:</b> $Revision: $Date: $)
 * </small>
 * @since OME3.0
 */
public class MessengerDialog 
	extends JDialog
	implements ActionListener, DocumentListener
{

	/** Identifies the error dialog type. */
	public static final int			ERROR_TYPE = 0;
	
	/** Identifies the error dialog type. */
	public static final int			COMMENT_TYPE = 1;
	
	/** Identifies the error dialog type. */
	public static final int			SUBMIT_ERROR_TYPE = 2;
	
	/** Bound property indicating to send the message. */
	public static final String		SEND_PROPERTY = "send";

	/** Bound property indicating to close the window. */
	public static final String		CLOSE_MESSENGER_PROPERTY = "closeMessenger";
	
	/** Action ID to close the dialog. */
	private static final int		CANCEL = 0;
	
	/** Action ID to send comment and close the dialog. */
	private static final int		SEND = 1;

	/** Action ID to copy on the clipboard. */
	private static final int		COPY = 3;
	
	/** Action ID to indicate the consequence of not submitting files. */
	private static final int		SUBMIT = 4;
	
	/** The default size of the window. */
	private static final Dimension 	DEFAULT_SIZE = new Dimension(700, 400);
	
	/** The tooltip of the {@link #cancelButton}. */
	private static final String		CANCEL_TOOLTIP = "Cancel your message";
	
	/** The tooltip of the {@link #sendButton}. */
	private static final String		SEND_TOOLTIP = "Send the information to " +
										"the development team";
	
	/** The tooltip of the {@link #copyButton}. */
	private static final String		COPY_TOOLTIP = "Copy the Exception " +
									"Message to the clipboard";
	
	/** The default message displayed. */
	private static final String		MESSAGE = "Thank you for taking the time " +
			"to send us your comments. \n\n" +
			"Your feedback will be used to further the development of " +
			"OMERO and improve our software. Any personal details you " +
			"provide are purely optional, and will only be used for " +
			"development purposes.\n";
	
	/** The default message displayed. */
	private static final String		DEBUG_MESSAGE = "An error message has " +
			"been generated by the application.\n\n" +
			"To help us improve our software, please fill " +
			"out the following form. Your personal details are purely " +
			"optional, and will only be used for development purposes.\n\n" +
			"Please note that your application may need to be restarted " +
			"to work properly.\n";
	
	/** The default message displayed. */
	private static final String		SUBMIT_MESSAGE = "Submit to the " +
			"development team the files that failed to import.\n\n" +
			"To help us improve our software, please fill " +
			"out the following form. Your personal details are purely " +
			"optional, and will only be used for development purposes.\n\n" +
			"Please note that your application may need to be restarted " +
			"to work properly.\n";
	
	/** The default message displayed when a non valid e-mail is entered. */
	private static final String		EMAIL_MESSAGE = "The e-mail address " +
			"entered \n does not seem to be valid. \n Please enter a new " +
			"e-mail address.";
	
	/** 
	 * The default message displayed if user decides not to submit the files. 
	 */
	private static final String		SUBMIT_FILES_MESSAGE = "Choosing not " +
			"to submit to the files will make it more difficult to " +
			"fix the problem you are experimenting.\nAre you sure " +
			"you do not want to submit the files?";
	
	/** Value of the  comment field. */
	private static final String		COMMENT_FIELD = "Comment: ";
	
	/** Value of the comment field when an exception is specified. */
	private static final String		DEBUG_COMMENT_FIELD ="What you were doing" +
														" when you crashed?";
	
	/** Value of the field. */
	private static final String		EMAIL_FIELD = "Email: ";
	
	/** The default tool-tip of the e-mail area. */
	private static final String 	EMAIL_TOOLTIP = "Enter your email " +
												"address here.";
	
	/** The e-mail field's suffix. */
	private static final String		EMAIL_SUFFIX = " (Optional)";

	/** Brief description of the error. */
	private static final String		ERROR_BRIEF = "Brief Description:";
	
	/** 
	 * One of the following constants: {@link #ERROR_TYPE} or 
	 * {@link #COMMENT_TYPE}.
	 */
	private int				dialogType;
	
	/** Button to close and dispose of the window. */
	private JButton 		cancelButton;
	
	/** Button to post the message. */
	private JButton			sendButton;

	/** The area displaying the <code>e-mail address</code>. */
	private JTextField		emailArea;
	
	/** The comment Area. */
	private MultilineLabel	commentArea;

	/** The e-mail address of the user submitting the message. */
	private String			emailAddress;
	
	/** The exception to handle, <code>null</code> if no exception. */
	private Exception		exception;
	
	/** The text pane displaying the error message. */
	private JTextPane		debugArea;
	
	/** Button to copy the message on the clipBoard. */
	private JButton			copyButton;
	
	/** The version of the server. */
	private String			serverVersion;
	
	/** A brief description of the error. */
	private String			errorDescription;
	
	/** The component displaying the files to send. */
	private FileTable		table;
	
	/** Indicates the status of the files submission. */
	private JXBusyLabel		submitStatus;
	
	/** Component indicating to submit the files or not. */
	private JCheckBox		submitFile;
	
	/** Indicates the progress of the files submission.*/
	private JXBusyLabel		progress;
	
	/** Indicates the progress of the files submission.*/
	private JLabel			progressLabel;

	/** 
	 * Displays the dialog indicating the consequence of not submitting
	 * the files.
	 */
	private void submitFilesControl()
	{
		if (!submitFile.isSelected()) {
			MessageBox dialog = new MessageBox(this, "Submit Files", 
					SUBMIT_FILES_MESSAGE);
			dialog.setResizable(false);
			if (dialog.centerMsgBox() == MessageBox.NO_OPTION)
				submitFile.setSelected(true);
		}
	}
	
	/**
	 * Formats the specified button.
	 * 
	 * @param b			The button to format.
	 * @param mnemonic	The key-code that indicates a mnemonic key.
	 * @param tooltip	The button's tooltip.
	 * @param actionID	The action id associated to the passed button.
	 */
	private void formatButton(JButton b, int mnemonic, String tooltip, int
			actionID)
	{
		b.setMnemonic(mnemonic);
        b.setOpaque(false);
        b.setToolTipText(tooltip);
        b.addActionListener(this);
        b.setActionCommand(""+actionID);
	}
    
    /** Hides the window and disposes. */
	private void close()
	{
		setVisible(false);
		dispose();
		firePropertyChange(CLOSE_MESSENGER_PROPERTY, Boolean.valueOf(false), 
				 Boolean.valueOf(true));
	}
	
	/** Copies the error message on the clipboard. */
	private void copy()
	{
		if (debugArea != null) {
			debugArea.selectAll();
			debugArea.copy();
		}
	}
	
	/**
	 * Sends the error to the server.
	 * 
	 * @param propertyName The name of the property.
	 */
	private void sendError(String propertyName)
	{
		String email = emailArea.getText().trim();
		String comment = commentArea.getText().trim();
		String error = null;
		if (debugArea != null)  error = debugArea.getText().trim();
		MessengerDetails details = new MessengerDetails(email, comment);
		details.setExtra(serverVersion);
		details.setError(error);
		firePropertyChange(propertyName, null, details);
		close();
	}
	
	/** 
	 * Sends the message. 
	 * 
	 * @param propertyName The name of the property to fire.
	 */
	private void send(String propertyName)
	{
		if (dialogType == SUBMIT_ERROR_TYPE) {
			List<FileTableNode> files = null;
			if (table != null) files = table.getSelectedFiles();
			if (CollectionUtils.isEmpty(files)) {
				sendError(propertyName);
			} else {
				String email = emailArea.getText().trim();
				String comment = commentArea.getText().trim();
				MessengerDetails details = new MessengerDetails(email, comment);
				details.setExtra(serverVersion);
				details.setObjectToSubmit(files);
				submitStatus.setVisible(true);
				submitStatus.setBusy(true);
				details.setExceptionOnly(!submitFile.isSelected());
				firePropertyChange(propertyName, null, details);
			}
		} else {
			sendError(propertyName);
		}
		sendButton.setEnabled(false);
	}
	
	/** Initializes the various components. */
	private void initComponents()
	{
		progress = new JXBusyLabel(new Dimension(16, 16));
		progress.setVisible(false);
		progressLabel = new JLabel();
		setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) { close(); }
		});
		cancelButton = new JButton("Cancel");
		formatButton(cancelButton, 'C', CANCEL_TOOLTIP, CANCEL);
		
		sendButton = new JButton("Send");
		formatButton(sendButton, 'S', SEND_TOOLTIP, SEND);
		
        emailArea = new JTextField(20);
        emailArea.setToolTipText(EMAIL_TOOLTIP);
        emailArea.setText(emailAddress);
        commentArea = new MultilineLabel();
        commentArea.setEditable(true);
        commentArea.setBackground(UIUtilities.BACKGROUND_COLOR);
        commentArea.setOpaque(true);
        if (exception != null) {
        	debugArea = buildExceptionArea();
        	copyButton = new JButton("Copy to Clipboard");
        	formatButton(copyButton, 'C', COPY_TOOLTIP, COPY);
        }
        //getRootPane().setDefaultButton(sendButton);
        setAlwaysOnTop(true);
        if (dialogType == COMMENT_TYPE) {
			sendButton.setEnabled(false);
			commentArea.getDocument().addDocumentListener(this);
		}
        submitStatus = new JXBusyLabel(new Dimension(16, 16));
        submitStatus.setText("Uploading files");
        submitStatus.setVisible(false);
        submitFile = new JCheckBox("Files");
        submitFile.setSelected(true);
        submitFile.addActionListener(this);
        submitFile.setActionCommand(""+SUBMIT);
	}

	/**
	 * Builds the UI component displaying the exception.
	 * 
	 * @return See above.
	 */
	private JTextPane buildExceptionArea()
	{
		JTextPane pane = UIUtilities.buildExceptionArea();
		StyledDocument document = pane.getStyledDocument();
		Style style = pane.getLogicalStyle();
		//Get the full debug text
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        exception.printStackTrace(pw);
        try {
        	document.insertString(document.getLength(), sw.toString(), style);
        } catch (BadLocationException e) {}
        
        return pane;
	}
	
	/**
	 * Builds and lays out the panel hosting the <code>comment</code> details.
	 * 
	 * @param comment		The comment's text.
	 * @param mnemonic 		The key-code that indicates a mnemonic key.
	 * @return See above.
	 */
	private JPanel buildCommentAreaPanel(String comment, int mnemonic)
	{
		JPanel panel = new JPanel();
        panel.setOpaque(false);
        
        double size[][] = {{TableLayout.FILL}, {20, TableLayout.FILL}};
        TableLayout layout = new TableLayout(size);
        panel.setLayout(layout);
        JScrollPane areaScrollPane = new JScrollPane(commentArea);
        areaScrollPane.setVerticalScrollBarPolicy(
        		JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        JLabel label = new JLabel(comment);
        label.setOpaque(false);
        label.setDisplayedMnemonic(mnemonic);
        panel.add(label, "0, 0, LEFT, CENTER");
        panel.add(areaScrollPane, "0, 1");
        return panel;
	}
	
	/**
	 * Builds and lays out the panel hosting the <code>email</code> details.
	 * 
	 * @param mnemonic The key-code that indicates a mnemonic key.
	 * @return See above.
	 */
	private JPanel buildEmailAreaPanel(int mnemonic)
	{
		double[][] size = null;
        
        JPanel panel = new JPanel();
        panel.setOpaque(false);
        
        if (EMAIL_SUFFIX.length() == 0)
            size = new double[][]{{TableLayout.PREFERRED, TableLayout.FILL}, 
        							{30}};
        else
            size = new double[][] 
                   {{TableLayout.PREFERRED,TableLayout.FILL, 
                	   TableLayout.PREFERRED}, {30}};
     
        TableLayout layout = new TableLayout(size);
        panel.setLayout(layout);       

        JLabel label = new JLabel(EMAIL_FIELD);
        label.setDisplayedMnemonic(mnemonic);
        label.setLabelFor(emailArea);
        label.setOpaque(false);

        panel.add(label, "0, 0, RIGHT, CENTER");        
        panel.add(emailArea, "1, 0, FULL, CENTER");

        if (EMAIL_SUFFIX.length() != 0)
            panel.add(new JLabel(EMAIL_SUFFIX), "2, 0, LEFT, CENTER");

		return panel;
	}
	
	/**
	 * Builds and lays out the panel hosting the debug information.
	 * 
	 * @return See above.
	 */
	private JPanel buildDebugPane()
	{
		JPanel panel = new JPanel();
		//panel.setBackground(UIUtilities.WINDOW_BACKGROUND_COLOR);
        panel.setOpaque(false);
        double tableSize[][] = {{TableLayout.FILL}, // columns
        						{TableLayout.FILL, 32}}; // rows
        TableLayout layout = new TableLayout(tableSize);
        panel.setLayout(layout);       
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        JScrollPane pane = new JScrollPane(debugArea);
        //pane.setBackground(UIUtilities.WINDOW_BACKGROUND_COLOR);
        panel.add(pane, "0, 0");
        panel.add(copyButton, "0, 1, CENTER, BOTTOM");
        return panel;
	}
	
	/**
	 * Builds and lays out the panel hosting the collection of files to submit.
	 * 
	 * @return See above.
	 */
	private JPanel buildFilesToSubmitPane(List<ImportErrorObject> toSubmit)
	{
		JPanel panel = new JPanel();
		//panel.setBackground(UIUtilities.WINDOW_BACKGROUND_COLOR);
        panel.setOpaque(false);
        
        
        double tableSize[][] = {{TableLayout.FILL}, // columns
        						{TableLayout.FILL}}; // rows
        TableLayout layout = new TableLayout(tableSize);
        panel.setLayout(layout);       
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        table = new FileTable(toSubmit);
        JScrollPane pane = new JScrollPane(table);
        //pane.setBackground(UIUtilities.WINDOW_BACKGROUND_COLOR);
        panel.add(pane, "0, 0");
        return panel;
	}
	
	/**
	 * Builds and lays out the panel hosting the comments.
	 * 
	 * @param comment		The comment's text.
	 * @return See above.
	 */
	private JPanel buildCommentPane(String comment)
	{
		JPanel commentPanel = new JPanel();
		//commentPanel.setBackground(UIUtilities.WINDOW_BACKGROUND_COLOR);
        int iconSpace = 0;
        double tableSize[][] =  {{iconSpace, (160 - iconSpace), 
        						TableLayout.FILL}, // columns
        						{0, 0, 30, TableLayout.FILL}}; // rows
	    TableLayout layout = new TableLayout(tableSize);
	    commentPanel.setLayout(layout);  
	    commentPanel.setBorder(
	    				BorderFactory.createEmptyBorder(10, 10, 10, 10));
	    commentPanel.add(buildEmailAreaPanel('E'), "0, 2, 2, 2");
	    commentPanel.add(buildCommentAreaPanel(comment, 'W'), "0, 3, 2, 3");
	    if (errorDescription != null && errorDescription.length() > 0) {
	    	layout.setRow(1, 30);
	    	JPanel p = new JPanel();
	    	p.add(UIUtilities.setTextFont(ERROR_BRIEF));
	    	p.add(new JLabel(errorDescription));
	    	commentPanel.add(UIUtilities.buildComponentPanel(p), "0, 1, 2, 1");
	    }
		return commentPanel;
	}
	
	/** 
	 * Builds the UI component hosting the debug information.
	 * 
	 * @param toSubmit The collection of files to send.
	 * @return See above
	 */
	private JTabbedPane buildExceptionPane(List<ImportErrorObject> toSubmit)
	{
        JTabbedPane tPane = new JTabbedPane();
        tPane.setOpaque(false);
        //tPane.setBackground(UIUtilities.WINDOW_BACKGROUND_COLOR);
       
        if (dialogType == SUBMIT_ERROR_TYPE) {
        	tPane.addTab("Comments", null, buildCommentPane(COMMENT_FIELD), 
        		"Your comments go here.");
        	tPane.addTab("Files to Send", null, 
        			buildFilesToSubmitPane(toSubmit),
        	"The files to send to the development team.");
        } else {
        	tPane.addTab("Comments", null, 
        			buildCommentPane(DEBUG_COMMENT_FIELD), 
        		"Your comments go here.");
        	tPane.addTab("Error Message", null, buildDebugPane(),
        	"The Exception Message.");
        }
		return tPane;
	}
	
    /**
     * Builds and lays out the buttons.
     * 
     * @param submit Pass <code>true</code> to display the submit files option,
     * 				 <code>false</code> otherwise.
     * @return See above.
     */
    private JPanel buildToolBar(boolean submit)
    {
    	JPanel bars = new JPanel();
    	bars.setLayout(new BoxLayout(bars, BoxLayout.X_AXIS));
    	if (submit) {
    		JPanel row = new JPanel();
    		row.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
    		row.add(new JLabel("Submit Exceptions and: "));
    		row.add(UIUtilities.buildComponentPanel(submitFile));
    		JPanel p = new JPanel();
    		p.setBorder(null);
    		p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
    		p.add(row);
    		JPanel progressPane = new JPanel();
    		progressPane.setLayout(new BoxLayout(progressPane,
    				BoxLayout.X_AXIS));
    		progressPane.add(progress);
    		progressPane.add(Box.createHorizontalStrut(5));
    		progressPane.add(progressLabel);
    		p.add(UIUtilities.buildComponentPanel(progressPane));
    		bars.add(UIUtilities.buildComponentPanel(p));
    	}
    	JPanel bar = new JPanel();
    	bar.setLayout(new BoxLayout(bar, BoxLayout.X_AXIS));
    	bar.add(cancelButton);
    	bar.add(Box.createHorizontalStrut(5));
    	bar.add(sendButton);
    	bar.add(Box.createHorizontalStrut(10));
    	bars.add(UIUtilities.buildComponentPanelRight(bar));
    	return bars;
    }
    
	/** 
	 * Builds and lays out the GUI. 
	 * 
	 * @param toSubmit The collection of files to send.
	 */
	private void buildGUI(List<ImportErrorObject> toSubmit)
	{
        JComponent component;
        Icon icon;
        IconManager icons = IconManager.getInstance();
        String message;
        if (dialogType == SUBMIT_ERROR_TYPE) {
        	message = SUBMIT_MESSAGE;
        	component = buildExceptionPane(toSubmit);
        	icon = icons.getIcon(IconManager.SUBMIT_ICON_64);
            if (icon == null) icon = UIManager.getIcon("OptionPane.errorIcon");
        } else if (exception == null) {
        	message = MESSAGE;
            icon = icons.getIcon(IconManager.COMMENT_ICON_64);
            if (icon == null)
            	icon = UIManager.getIcon("OptionPane.questionIcon");
        	component = buildCommentPane(COMMENT_FIELD);
        } else {
        	message = DEBUG_MESSAGE;
        	component = buildExceptionPane(null);
        	icon = icons.getIcon(IconManager.ERROR_ICON_64);
            if (icon == null) icon = UIManager.getIcon("OptionPane.errorIcon");
        }
        Container c = getContentPane();
        TitlePanel tp = new TitlePanel(getTitle(), message, icon);
        c.setLayout(new BorderLayout(0, 0));
        c.add(tp, BorderLayout.NORTH);
		c.add(component, BorderLayout.CENTER);
		c.add(buildToolBar(toSubmit != null && toSubmit.size() > 0), 
				BorderLayout.SOUTH);
	}
	
	/** 
	 * Initializes the dialog.
	 * 
	 *  @param title 	The title of the dialog.
	 *  @param toSubmit The collection of files to send.
	 */
	private void initialize(String title, List<ImportErrorObject> toSubmit)
	{
		setTitle(title);
		initComponents();
		buildGUI(toSubmit);
		setSize(DEFAULT_SIZE);
	}
	
	/**
	 * Creates a new instance.
	 * 
	 * @param parent		The parent of this dialog.
	 * @param title			The dialog's title.
	 * @param emailAddress	The e-mail address of the current user.
	 */
	public MessengerDialog(JFrame parent, String title, String emailAddress)
	{
		super(parent);
		this.emailAddress = emailAddress;
		dialogType = COMMENT_TYPE;
		initialize(title, null);
	}
	
	/**
	 * Creates a new instance.
	 * 
	 * @param parent		The parent of this dialog.
	 * @param title			The dialog's title.
	 * @param emailAddress	The e-mail address of the current user.
	 * @param exception		The exception to handle.
	 */
	public MessengerDialog(JFrame parent, String title, String emailAddress, 
						Exception exception)
	{
		super(parent);
		dialogType = ERROR_TYPE;
		this.emailAddress = emailAddress;
		this.exception = exception;
		initialize(title, null);
	}	
	
	/**
	 * Creates a new instance.
	 * 
	 * @param parent		The parent of this dialog.
	 * @param title			The dialog's title.
	 * @param emailAddress	The e-mail address of the current user.
	 * @param toSubmit		The object to submit.
	 */
	public MessengerDialog(JFrame parent, String title, String emailAddress, 
						List<ImportErrorObject> toSubmit)
	{
		super(parent);
		this.dialogType = SUBMIT_ERROR_TYPE;
		this.emailAddress = emailAddress;
		initialize(title, toSubmit);
	}	
	
	/**
	 * Sets a brief description of the error.
	 * 
	 * @param description The value to set.
	 */
	public void setErrorDescription(String description)
	{
		errorDescription = description;
	}
	
	/**
	 * Sets the comment to send.
	 * 
	 * @param comment The text to display.
	 */
	public void setComment(String comment) 
	{
		if (comment != null && comment.trim().length() > 0)
			commentArea.setText(comment);
	}
	
	/** 
	 * Sets the version of the server.
	 * 
	 * @param serverVersion The value to set.
	 */
	public void setServerVersion(String serverVersion)
	{ 
		this.serverVersion = serverVersion; 
	}
	
	/**
	 * Returns the type associated to this widget. 
	 * 
	 * @return See above.
	 */
	public int getDialogType() { return dialogType; }

	/**
	 * Sets the status of the file submission.
	 * 
	 * @param text The text to display.
	 * @param hide Pass <code>true</code> to hide the progress,
	 * 				<code>false</code> otherwise.
	 */
	public void setSubmitStatus(String text, boolean hide)
	{
		progressLabel.setText(text);
		progress.setVisible(!hide);
		progress.setBusy(!hide);
	}
	
	/**
	 * Reacts to click on controls.
	 * @see ActionListener#actionPerformed(ActionEvent)
	 */
	public void actionPerformed(ActionEvent e)
	{
		int index = Integer.parseInt(e.getActionCommand());
		switch (index) {
			case CANCEL:
				close();
				break;
			case SEND:
				send(SEND_PROPERTY);
				break;
			case COPY:
				copy();
				break;
			case SUBMIT:
				submitFilesControl();
		}
	}
	
	/**
	 * Sets the enabled flag of the {@link #sendButton} depending on the 
	 * type of dialog we handle.
	 * @see DocumentListener#insertUpdate(DocumentEvent)
	 */
	public void insertUpdate(DocumentEvent e)
	{
		if (dialogType == COMMENT_TYPE) {
			String text = commentArea.getText();
			sendButton.setEnabled(text != null && text.trim().length() > 0);
		}
	}

	/**
	 * Sets the enabled flag of the {@link #sendButton} depending on the 
	 * type of dialog we handle.
	 * @see DocumentListener#removeUpdate(DocumentEvent)
	 */
	public void removeUpdate(DocumentEvent e)
	{
		if (dialogType == COMMENT_TYPE) {
			String text = commentArea.getText();
			sendButton.setEnabled(text != null && text.trim().length() > 0);
		}
	}
	
	/**
	 * Required by the {@link DocumentListener} I/F but no-op implementation
	 * in our case.
	 * @see DocumentListener#changedUpdate(DocumentEvent)
	 */
	public void changedUpdate(DocumentEvent e) {}
	
}
