/*******************************************************************************
 * Copyright (c) 2000, 2013 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IBM Corporation - initial API and implementation
 *    Austin Riddle (Texas Center for Applied Technology) - RAP implementation
 *    EclipseSource - ongoing development
 *******************************************************************************/
package org.eclipse.swt.widgets;

import java.io.File;
import java.util.ArrayList;

import org.eclipse.rap.rwt.graphics.Graphics;
import org.eclipse.rap.rwt.internal.textsize.TextSizeUtil;
import org.eclipse.rap.rwt.lifecycle.UICallBack;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.widgets.ExtensionValidationStrategy;
import org.eclipse.swt.internal.widgets.ProgressCollector;
import org.eclipse.swt.internal.widgets.UploadPanel;
import org.eclipse.swt.internal.widgets.ValidationHandler;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;


/**
 * Instances of this class allow the user to navigate the file system and select
 * a file name. The selected file will be uploaded to the server and the path
 * made available as the result of the dialog.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd><!--SAVE, OPEN,--> MULTI</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * The OPEN style is applied by default and setting any other styles has no
 * effect. <!--Note: Only one of the styles SAVE and OPEN may be specified.-->
 * </p>
 * <p>
 * IMPORTANT: This class is intended to be subclassed <em>only</em> within the
 * SWT implementation.
 * </p>
 *
 * @see <a href="http://www.eclipse.org/swt/snippets/#filedialog">FileDialog
 *      snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
 *      ControlExample, Dialog tab</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further
 *      information</a>
 */
@SuppressWarnings("restriction")
public class FileDialog extends Dialog {
  private static final long serialVersionUID = 1L;

  // RAP implementation fields taken from JFace
  private final static int HORIZONTAL_DIALOG_UNIT_PER_CHAR = 4;
  private final static int BUTTON_WIDTH = 61;
  // SWT FileDialog API fields
  String[] filterNames = new String[ 0 ];
  String[] filterExtensions = new String[ 0 ];
  String[] fileNames = new String[ 0 ];
  String filterPath = "";
  String fileName;
  int filterIndex;
  boolean overwrite = false;
  // RAP implementation fields
  private java.util.List<UploadPanel> uploadPanels;
  private Button okButton;
  private ProgressBar totalProgressBar;
  private Combo filterSelector;
  private Button addFileSelectorButton;
  private Composite scrollChild;
  private Composite uploadsWrapper;
  private ScrolledComposite uploadScroller;
  private boolean autoUpload;
  private boolean uploadLocked;
  private ProgressCollector progressCollector;
  private ValidationHandler validationHandler;
  private Image addImage;

  /**
   * Constructs a new instance of this class given only its parent.
   *
   * @param parent a shell which will be the parent of the new instance
   * @exception IllegalArgumentException <ul>
   *              <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
   *              </ul>
   * @exception SWTException <ul>
   *              <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
   *              thread that created the parent</li>
   *              <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed
   *              subclass</li>
   *              </ul>
   */
  public FileDialog( Shell parent ) {
    this( parent, SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL );
  }

  /**
   * Constructs a new instance of this class given its parent and a style value
   * describing its behavior and appearance.
   * <p>
   * The style value is either one of the style constants defined in class
   * <code>SWT</code> which is applicable to instances of this class, or must be
   * built by <em>bitwise OR</em>'ing together (that is, using the
   * <code>int</code> "|" operator) two or more of those <code>SWT</code> style
   * constants. The class description lists the style constants that are
   * applicable to the class. Style bits are also inherited from superclasses.
   * </p>
   *
   * @param parent a shell which will be the parent of the new instance
   * @param style the style of dialog to construct
   * @exception IllegalArgumentException <ul>
   *              <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
   *              </ul>
   * @exception SWTException <ul>
   *              <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
   *              thread that created the parent</li>
   *              <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed
   *              subclass</li>
   *              </ul>
   */
  public FileDialog( Shell parent, int style ) {
    super( parent, checkStyle( parent, style ) );
    checkSubclass();
  }

  static int checkStyle( Shell parent, int style ) {
    int result = style;
    int mask = SWT.PRIMARY_MODAL | SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL;
    if( ( result & SWT.SHEET ) != 0 ) {
      result &= ~SWT.SHEET;
      if( ( result & mask ) == 0 ) {
        result |= parent == null ? SWT.APPLICATION_MODAL : SWT.PRIMARY_MODAL;
      }
    }
    if( ( result & mask ) == 0 ) {
      result |= SWT.APPLICATION_MODAL;
    }
    if( ( result & ( SWT.LEFT_TO_RIGHT ) ) == 0 ) {
      if( parent != null ) {
        if( ( parent.getStyle() & SWT.LEFT_TO_RIGHT ) != 0 ) {
          result |= SWT.LEFT_TO_RIGHT;
        }
      }
    }
    // [if] force SWT.TITLE as in SWT titlebar is always shown
    result |= SWT.TITLE;
    // [if] Min button has no sense in RAP
    result &= ~SWT.MIN;
    return result;
  }

  /**
   * Returns the path of the first file that was selected in the dialog relative
   * to the filter path, or an empty string if no such file has been selected.
   *
   * @return the relative path of the file
   */
  public String getFileName() {
    return fileName;
  }

  /**
   * Returns a (possibly empty) array with the paths of all files that were
   * selected in the dialog relative to the filter path.
   *
   * @return the relative paths of the files
   */
  public String[] getFileNames() {
    return fileNames;
  }

  /**
   * Returns the file extensions which the dialog will use to filter the files
   * it shows.
   *
   * @return the file extensions filter
   */
  public String[] getFilterExtensions() {
    return filterExtensions;
  }

  /**
   * Get the 0-based index of the file extension filter which was selected by
   * the user, or -1 if no filter was selected.
   * <p>
   * This is an index into the FilterExtensions array and the FilterNames array.
   * </p>
   *
   * @return index the file extension filter index
   * @see #getFilterExtensions
   * @see #getFilterNames
   */
  public int getFilterIndex() {
    return filterIndex;
  }

  /**
   * Returns the names that describe the filter extensions which the dialog will
   * use to filter the files it shows.
   *
   * @return the list of filter names
   */
  public String[] getFilterNames() {
    return filterNames;
  }

  /**
   * Returns the directory path that the dialog will use, or an empty string if
   * this is not set. File names in this path will appear in the dialog,
   * filtered according to the filter extensions.
   *
   * @return the directory path string
   * @see #setFilterExtensions
   */
  public String getFilterPath() {
    return filterPath;
  }

  /**
   * Returns the flag that the dialog will use to determine whether to prompt
   * the user for file overwrite if the selected file already exists.
   *
   * @return true if the dialog will prompt for file overwrite, false otherwise
   */
  public boolean getOverwrite() {
    return overwrite;
  }

  /**
   * Set the initial filename which the dialog will select by default when
   * opened to the argument, which may be null. The name will be prefixed with
   * the filter path when one is supplied.
   *
   * @param string the file name
   */
  public void setFileName( String string ) {
    fileName = string;
  }

  /**
   * Set the file extensions which the dialog will use to filter the files it
   * shows to the argument, which may be null.
   * <p>
   * The strings are platform specific. For example, on some platforms, an
   * extension filter string is typically of the form "*.extension", where "*.*"
   * matches all files. For filters with multiple extensions, use semicolon as a
   * separator, e.g. "*.jpg;*.png".
   * </p>
   *
   * @param extensions the file extension filter
   * @see #setFilterNames to specify the user-friendly names corresponding to
   *      the extensions
   */
  public void setFilterExtensions( String[] extensions ) {
    filterExtensions = extensions;
  }

  /**
   * Set the 0-based index of the file extension filter which the dialog will
   * use initially to filter the files it shows to the argument.
   * <p>
   * This is an index into the FilterExtensions array and the FilterNames array.
   * </p>
   *
   * @param index the file extension filter index
   * @see #setFilterExtensions
   * @see #setFilterNames
   */
  public void setFilterIndex( int index ) {
    filterIndex = index;
  }

  /**
   * Sets the names that describe the filter extensions which the dialog will
   * use to filter the files it shows to the argument, which may be null.
   * <p>
   * Each name is a user-friendly short description shown for its corresponding
   * filter. The <code>names</code> array must be the same length as the
   * <code>extensions</code> array.
   * </p>
   *
   * @param names the list of filter names, or null for no filter names
   * @see #setFilterExtensions
   */
  public void setFilterNames( String[] names ) {
    filterNames = names;
  }

  /**
   * Sets the directory path that the dialog will use to the argument, which may
   * be null. File names in this path will appear in the dialog, filtered
   * according to the filter extensions. If the string is null, then the
   * operating system's default filter path will be used.
   * <p>
   * Note that the path string is platform dependent. For convenience, either
   * '/' or '\' can be used as a path separator.
   * </p>
   *
   * @param string the directory path
   * @see #setFilterExtensions
   */
  public void setFilterPath( String string ) {
    filterPath = string;
  }

  /**
   * Sets the flag that the dialog will use to determine whether to prompt the
   * user for file overwrite if the selected file already exists.
   *
   * @param overwrite true if the dialog will prompt for file overwrite, false
   *          otherwise
   */
  public void setOverwrite( boolean overwrite ) {
    this.overwrite = overwrite;
  }

  /**
   * Sets the auto-upload state of the dialog. If true, the dialog will start
   * uploading files immediately after they are selected. In any case, if the
   * dialog is canceled, files are not made available to the application.
   * <p>
   * <strong>Note:</strong> this method is <em>not</em> part of the SWT API. It
   * only exists in the RWT version.
   * </p>
   *
   * @param autoUpload <code>true</code> to set the dialog into autoupload mode,
   *          <code>false</code> otherwise
   */
  public void setAutoUpload( boolean autoUpload ) {
    this.autoUpload = autoUpload;
  }

  /**
   * Returns the auto-upload state of the dialog. If true, the dialog will
   * upload files automatically as they are selected.
   * <p>
   * <strong>Note:</strong> this method is <em>not</em> part of the SWT API. It
   * only exists in the RWT version.
   * </p>
   *
   * @return <code>true</code> if the dialog is configured to auto upload files,
   *         <code>false</code> otherwise
   */
  public boolean getAutoUpload() {
    return autoUpload;
  }

  public String open() {
    prepareOpen();
    runEventLoop( shell );
    return fileName;
  }

  @Override
  protected void prepareOpen() {
    UICallBack.activate( FileDialog.class.getName() + hashCode() );
    initializeDefaults();
    createShell();
    createControls();
    layoutAndCenterShell();
  }

  private void initializeDefaults() {
    uploadPanels = new ArrayList<UploadPanel>();
    uploadLocked = false;
    // [ar] - add a strategy for content type?
    ExtensionValidationStrategy validationStrategy
      = new ExtensionValidationStrategy( filterExtensions, filterIndex );
    validationHandler = new ValidationHandler() {
      @Override
      public void updateEnablement() {
        FileDialog.this.updateEnablement();
      }
    };
    validationHandler.addValidationStrategy( validationStrategy );
    progressCollector = new ProgressCollector( validationHandler );
    validationHandler.setNumUploads( uploadPanels.size() );
  }

  private void createShell() {
    // int style = SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL;
    shell = new Shell( getParent(), getStyle() );
    shell.setText( getText() );
    shell.addShellListener( new ShellAdapter() {
      @Override
      public void shellClosed( ShellEvent e ) {
        handleShellClose();
      }
    } );
  }

  private void layoutAndCenterShell() {
    Point prefSize = shell.computeSize( SWT.DEFAULT, SWT.DEFAULT );
    prefSize.x += 50;
    prefSize.y += 10;
    if( allowMultiple() ) {
      // leave room for five upload slots + add button
      prefSize.y += 100;
    }
    shell.setSize( prefSize );
    shell.setMinimumSize( prefSize );
    Rectangle parentSize = getParent().getBounds();
    int locationX = ( parentSize.width - prefSize.x ) / 2 + parentSize.x;
    int locationY = ( parentSize.height - prefSize.y ) / 2 + parentSize.y;
    shell.setLocation( locationX, locationY );
  }

  private void createControls() {
    GridLayout mainLayout = new GridLayout();
    mainLayout.marginWidth = 10;
    mainLayout.marginHeight = 10;
    mainLayout.horizontalSpacing = 10;
    mainLayout.verticalSpacing = 10;
    shell.setLayout( mainLayout );
    createDialogArea( shell );
    createButtonArea( shell );
  }

  private boolean allowMultiple() {
    return ( getStyle() & ( SWT.MULTI ) ) != 0;
  }

  private Control createDialogArea( Composite parentComposite ) {
    // create a composite with standard margins and spacing
    Composite main = new Composite( parentComposite, SWT.NONE );
    main.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
    GridLayout layout = new GridLayout( 1, true );
    layout.marginWidth = 0;
    layout.marginHeight = 0;
    main.setLayout( layout );
    if( allowMultiple() ) {
      createMultiSelector( main );
    } else {
      createSingleSelector( main );
    }
    Composite footerComp = new Composite( main, SWT.NONE );
    GridLayout footerLayout = new GridLayout( 2, false );
    footerLayout.marginWidth = 0;
    footerLayout.marginHeight = 0;
    footerComp.setLayout( footerLayout );
    footerComp.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
    if( allowMultiple() ) {
      createAddSelectorButton( scrollChild );
    }
    filterSelector = createFilterSelector( footerComp );
    filterSelector.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
    totalProgressBar = new ProgressBar( footerComp, SWT.HORIZONTAL | SWT.SMOOTH );
    totalProgressBar.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
    totalProgressBar.setToolTipText( "Total upload progress" );
    totalProgressBar.setMaximum( 100 );
    progressCollector.setProgressBar( totalProgressBar );
    return main;
  }

  private void createSingleSelector( Composite main ) {
    UploadPanel uploadPanel = new UploadPanel( main, UploadPanel.FULL );
    uploadPanel.setValidationHandler( validationHandler );
    uploadPanel.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
    uploadPanel.setProgressCollector( progressCollector );
    uploadPanel.setAutoUpload( getAutoUpload() );
    uploadPanels.add( uploadPanel );
    validationHandler.setNumUploads( uploadPanels.size() );
  }

  private void createMultiSelector( Composite main ) {
    uploadScroller = new ScrolledComposite( main, SWT.V_SCROLL | SWT.BORDER );
    uploadScroller.setExpandHorizontal( true );
    uploadScroller.setExpandVertical( true );
    GridData uploadScrollerLayoutData = new GridData( SWT.FILL, SWT.FILL, true, true );
    uploadScroller.setLayoutData( uploadScrollerLayoutData );
    scrollChild = new Composite( uploadScroller, SWT.NONE );
    GridLayout scrollChildLayout = new GridLayout( 1, true );
    scrollChild.setLayout( scrollChildLayout );
    uploadsWrapper = new Composite( scrollChild, SWT.NONE );
    GridLayout uploadWrapperLayout = new GridLayout( 1, true );
    // [if] marginBottom = 1 is needed to avoid default composite size (64) if it is empty
    uploadWrapperLayout.marginBottom = 1;
    uploadWrapperLayout.marginWidth = 0;
    uploadWrapperLayout.marginHeight = 0;
    uploadsWrapper.setLayout( uploadWrapperLayout );
    uploadsWrapper.setLayoutData( new GridData( SWT.FILL, SWT.TOP, true, false ) );
    addUploadPanel();
    uploadScroller.setContent( scrollChild );
    uploadScroller.setMinSize( scrollChild.computeSize( SWT.DEFAULT, SWT.DEFAULT ) );
  }

  private void createAddSelectorButton( Composite parent ) {
    addFileSelectorButton = new Button( parent, SWT.PUSH );
    if( addImage == null ) {
      addImage = Graphics.getImage( "resources/add_obj.gif", getClass().getClassLoader() );
    }
    addFileSelectorButton.setImage( addImage );
    addFileSelectorButton.setToolTipText( "Add file" );
    addFileSelectorButton.addSelectionListener( new SelectionAdapter() {
      @Override
      public void widgetSelected( SelectionEvent e ) {
        final UploadPanel uploadPanel = addUploadPanel();
        progressCollector.updateTotalProgress();
        uploadScroller.setMinSize( scrollChild.computeSize( SWT.DEFAULT, SWT.DEFAULT ) );
        // [if] workaround for ScrolledComposite scroll issue - see bug 349301 and 349301
        uploadPanel.setEnabled( false );
        uploadPanel.setVisible( false );
        uploadScroller.getDisplay().timerExec( 10, new Runnable() {
          public void run() {
            uploadPanel.setEnabled( true );
            uploadPanel.setVisible( true );
            int scrollTop = scrollChild.getSize().y - uploadScroller.getClientArea().y;
            uploadScroller.setOrigin( 0, Math.max(  0, scrollTop ) );
          }
        } );
      }
    } );
  }

  private UploadPanel addUploadPanel() {
    int uploadPanelStyle = UploadPanel.COMPACT | UploadPanel.PROGRESS | UploadPanel.REMOVEABLE;
    final UploadPanel uploadPanel= new UploadPanel( uploadsWrapper, uploadPanelStyle );
    uploadPanel.addDisposeListener( new DisposeListener() {
      public void widgetDisposed( DisposeEvent event ) {
        Display.getCurrent().asyncExec( new Runnable() {
          public void run() {
            if( !uploadsWrapper.isDisposed() ) {
              uploadPanels.remove( uploadPanel );
              validationHandler.setNumUploads( uploadPanels.size() );
              scrollChild.pack( true );
              progressCollector.updateTotalProgress();
              uploadScroller.setMinSize( scrollChild.computeSize( SWT.DEFAULT, SWT.DEFAULT ) );
              updateEnablement();
            }
          }
        } );
      }
    } );
    uploadPanel.setValidationHandler( validationHandler );
    uploadPanel.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
    uploadPanel.setProgressCollector( progressCollector );
    uploadPanel.setAutoUpload( getAutoUpload() );
    uploadPanels.add( uploadPanel );
    validationHandler.setNumUploads( uploadPanels.size() );
    scrollChild.pack( true );
    updateEnablement();
    return uploadPanel;
  }

  private Combo createFilterSelector( Composite headerComp ) {
    final Combo filterCombo = new Combo( headerComp, SWT.DROP_DOWN | SWT.READ_ONLY );
    filterCombo.setToolTipText( "Selected filename filter" );
    String[] names = getFilterNames();
    String[] exts = getFilterExtensions();
    if( ( names == null || names.length == 0 ) && ( exts == null || exts.length == 0 ) ) {
      names = new String[]{
        "All Files"
      };
      exts = new String[]{
        "*.*"
      };
    }
    for( int i = 0; i < exts.length; i++ ) {
      StringBuffer sb = new StringBuffer();
      if( names != null && i < names.length ) {
        sb.append( names[ i ] ).append( " " );
      }
      sb.append( "(" );
      sb.append( exts[ i ] );
      sb.append( ")" );
      filterCombo.add( sb.toString() );
    }
    filterCombo.select( getFilterIndex() );
    filterCombo.addSelectionListener( new SelectionAdapter() {
      @Override
      public void widgetSelected( SelectionEvent e ) {
        setFilterIndex( filterCombo.getSelectionIndex() );
        for( int i = 0; i < uploadPanels.size(); i++ ) {
          UploadPanel panel = uploadPanels.get( i );
          panel.validate();
        }
      }
    } );
    return filterCombo;
  }

  private void createButtonArea( Composite parent ) {
    Composite buttonComposite = new Composite( parent, SWT.NONE );
    GridData layoutData = new GridData( SWT.RIGHT, SWT.CENTER, false, false );
    layoutData.horizontalSpan = 2;
    buttonComposite.setLayoutData( layoutData );
    GridLayout buttonCompLayout = new GridLayout( 2, false );
    buttonCompLayout.marginWidth = 0;
    buttonCompLayout.marginHeight = 0;
    buttonComposite.setLayout( buttonCompLayout );
    String okText = SWT.getMessage( "SWT_OK" );
    okButton = createButton( buttonComposite, okText );
    parent.getShell().setDefaultButton( okButton );
    okButton.forceFocus();
    String cancelText = SWT.getMessage( "SWT_Cancel" );
    Button cancelButton = createButton( buttonComposite, cancelText );
    okButton.addSelectionListener( new SelectionAdapter() {
      @Override
      public void widgetSelected( SelectionEvent e ) {
        startUploads();
      }
    } );
    cancelButton.addSelectionListener( new SelectionAdapter() {
      @Override
      public void widgetSelected( SelectionEvent e ) {
        closeShell();
      }
    } );
    updateEnablement();
  }

  // [if] Calling shell.close() in the selection listener directly throws IllegalAccessError
  // see bug 253818
  private void closeShell() {
    shell.close();
  }

  private Button createButton( Composite parent, String text ) {
    Button result = new Button( parent, SWT.PUSH );
    result.setText( text );
    GridData data = new GridData( GridData.HORIZONTAL_ALIGN_FILL );
    Font dialogFont = result.getFont();
    float charWidth = TextSizeUtil.getAvgCharWidth( dialogFont );
    float width = charWidth * BUTTON_WIDTH + HORIZONTAL_DIALOG_UNIT_PER_CHAR / 2;
    int widthHint = ( int )( width / HORIZONTAL_DIALOG_UNIT_PER_CHAR );
    Point minSize = result.computeSize( SWT.DEFAULT, SWT.DEFAULT, true );
    data.widthHint = Math.max( widthHint, minSize.x );
    result.setLayoutData( data );
    return result;
  }

  private void startUploads() {
    java.util.List<UploadPanel> needsProcessing = new ArrayList<UploadPanel>();
    for( int i = 0; i < uploadPanels.size(); i++ ) {
      UploadPanel panel = uploadPanels.get( i );
      if( !panel.isFinished() ) {
        needsProcessing.add( panel );
      }
    }
    uploadLocked = true;
    if( needsProcessing.size() > 0 ) {
      okButton.setText( "Uploading..." );
      okButton.setToolTipText( "Waiting for uploads to finish" );
      okButton.setEnabled( false );
      if( addFileSelectorButton != null ) {
        addFileSelectorButton.setEnabled( false );
      }
      for( int i = 0; i < needsProcessing.size(); i++ ) {
        UploadPanel panel = needsProcessing.get( i );
        if( !panel.isStarted() ) {
          panel.startUpload();
        }
        panel.setEnabled( false );
      }
    }
    updateEnablement();
  }

  private void updateEnablement() {
    if( okButton != null && !okButton.isDisposed() ) {
      String okText = SWT.getMessage( "SWT_OK" );
      if( uploadPanels.size() == 0 ) {
        okButton.setText( okText );
        okButton.setEnabled( false );
      } else if( uploadPanels.size() > 0 ) {
        boolean enabled = true;
        if( uploadLocked ) {
          if( progressCollector.isFinished() ) {
            okButton.setText( okText );
            fileNames = new String[ uploadPanels.size() ];
            fileName = null;
            for( int i = 0; i < uploadPanels.size(); i++ ) {
              UploadPanel uploadPanel = uploadPanels.get( i );
              File uploadedFile = uploadPanel.getUploadedFile();
              // TODO [rst] Understand if file can be null
              if( uploadedFile != null ) {
                fileNames[ i ] = uploadedFile.getAbsolutePath();
              }
              if( fileName == null || fileName.length() == 0 ) {
                fileName = fileNames[ 0 ];
              }
            }
            shell.close();
          } else {
            okButton.setText( "Uploading..." );
            okButton.setToolTipText( "Waiting for uploads to finish" );
            okButton.setEnabled( false );
          }
        } else {
          okButton.setText( okText );
          for( int i = 0; i < uploadPanels.size(); i++ ) {
            UploadPanel panel = uploadPanels.get( i );
            if( panel.getSelectedFilename().length() == 0 ) {
              enabled = false;
            }
          }
          if( !enabled ) {
            okButton.setToolTipText( "Specify files in all empty selectors to continue." );
          } else {
            okButton.setToolTipText( "" );
          }
          okButton.setEnabled( enabled );
        }
      }
    }
  }

  private void cleanup() {
    UICallBack.deactivate( FileDialog.class.getName() + hashCode() );
  }

  private void handleShellClose() {
    cleanup();
  }
}
