/******************************************************************************
 * Copyright (c) 2008 Oracle
 * 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:
 *    Konstantin Komissarchik - initial implementation and ongoing maintenance
 ******************************************************************************/

package org.eclipse.wst.common.project.facet.ui.internal;

import static java.lang.Math.max;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gd;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdfill;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdhfill;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdhhint;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdhspan;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdwhint;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gl;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.glmargins;
import static org.eclipse.wst.common.project.facet.ui.internal.util.SwtUtil.getPreferredWidth;
import static org.eclipse.wst.common.project.facet.ui.internal.util.SwtUtil.runOnDisplayThread;

import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.CompositeImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
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.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.common.project.facet.core.ICategory;
import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
import org.eclipse.wst.common.project.facet.core.IPreset;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
import org.eclipse.wst.common.project.facet.core.events.IProjectFacetsChangedEvent;
import org.eclipse.wst.common.project.facet.core.internal.ProjectFacet;
import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager;
import org.eclipse.wst.common.project.facet.core.runtime.events.IRuntimeLifecycleEvent;
import org.eclipse.wst.common.project.facet.core.runtime.events.IRuntimeLifecycleListener;
import org.eclipse.wst.common.project.facet.ui.IDecorationsProvider;
import org.eclipse.wst.common.project.facet.ui.ModifyFacetedProjectWizard;
import org.eclipse.wst.common.project.facet.ui.internal.util.BasicToolTip;
import org.eclipse.wst.common.project.facet.ui.internal.util.HeaderToolTip;
import org.eclipse.wst.common.project.facet.ui.internal.util.ReadOnlyComboBoxCellEditor;
import org.osgi.framework.Bundle;

/**
 * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
 */

public final class FacetsSelectionPanel

    extends Composite
    implements ISelectionProvider

{
    private static final String CW_FACET = "cw.facet"; //$NON-NLS-1$
    private static final String CW_VERSION = "cw.version"; //$NON-NLS-1$
    private static final String SASH1W1 = "sash.1.weight.1"; //$NON-NLS-1$
    private static final String SASH1W2 = "sash.1.weight.2"; //$NON-NLS-1$
    private static final String SASH2W1 = "sash.2.weight.1"; //$NON-NLS-1$
    private static final String SASH2W2 = "sash.2.weight.2"; //$NON-NLS-1$
    
    private static final String IMG_DOWN_ARROW = "##down-arrow##"; //$NON-NLS-1$
    
    private final Composite topComposite;
    private final SashForm sform1;
    private final SashForm sform2;
    private final Label presetsLabel;
    private final Combo presetsCombo;
    private final Button savePresetButton;
    private final Button deletePresetButton;
    private final CheckboxTreeViewer treeViewer;
    private final Tree tree;
    private final TreeViewerColumn colFacet;
    private final TreeViewerColumn colVersion;
    private final FixedFacetToolTip fixedFacetToolTip;
    private final Menu popupMenu;
    private final MenuItem popupMenuLockUnlock;
    private final MenuItem popupMenuChangeVersion;
    private final TableViewer problemsView;
    private final TabItem detailsTabItem;
    private final DetailsPanel detailsPanel;
    private final TabItem runtimesTabItem;
    private final RuntimesPanel runtimesPanel;
    
    private final IDialogSettings settings;
    private boolean showToolTips;
    
    
    private final IFacetedProjectWorkingCopy fpjwc;
    private final List<IFacetedProjectListener> registeredWorkingCopyListeners;
    private final Map<IProjectFacet,IProjectFacetVersion> selectedVersions;
    private final List<ISelectionChangedListener> selectionListeners;
    private Object selection;
    
    /**
     * Holds images used throughout the panel.
     */
    
    private final ImageRegistry imageRegistry;
    
    private final IRuntimeLifecycleListener runtimeLifecycleListener;
    
    public interface IFilter 
    {
        boolean check( IProjectFacetVersion fv );
    }

    public FacetsSelectionPanel( final Composite parent,
                                 final IFacetedProjectWorkingCopy fpjwc )
    {
        super( parent, SWT.NONE );

        this.fpjwc = fpjwc;
        this.registeredWorkingCopyListeners = new ArrayList<IFacetedProjectListener>(); 
        this.selectedVersions = new HashMap<IProjectFacet,IProjectFacetVersion>();
        this.selection = null;
        this.selectionListeners = new ArrayList<ISelectionChangedListener>();
        this.showToolTips = false;
        
        // Initialize the image registry.
        
        this.imageRegistry = new ImageRegistry();
        final Bundle bundle = Platform.getBundle( FacetUiPlugin.PLUGIN_ID );
        
        URL url = bundle.getEntry( "images/down-arrow.gif" ); //$NON-NLS-1$
        this.imageRegistry.put( IMG_DOWN_ARROW, ImageDescriptor.createFromURL( url ) );

        // Read the dialog settings.

        final IDialogSettings root
            = FacetUiPlugin.getInstance().getDialogSettings();

        IDialogSettings temp = root.getSection( getClass().getName() );

        if( temp == null )
        {
            temp = root.addNewSection( getClass().getName() );
        }
        
        this.settings = temp;

        // Layout the panel.

        setLayout( glmargins( gl( 1 ), 0, 0 ) );
        
        this.topComposite = new Composite( this, SWT.NONE );
        this.topComposite.setLayout( glmargins( gl( 4 ), 0, 0 ) );
        this.topComposite.setLayoutData( gdfill() );
        
        this.presetsLabel = new Label( this.topComposite, SWT.NONE );
        this.presetsLabel.setText( Resources.presetsLabel );
        
        this.presetsCombo = new Combo( this.topComposite, SWT.READ_ONLY );
        this.presetsCombo.setLayoutData( gdhfill() );
        
        this.savePresetButton = new Button( this.topComposite, SWT.PUSH );
        this.savePresetButton.setText( Resources.saveButtonLabel );
        
        this.savePresetButton.addSelectionListener
        (
            new SelectionAdapter()
            {
                public void widgetSelected( final SelectionEvent e )
                {
                    handleSavePreset();
                }
            }
        );

        this.deletePresetButton = new Button( this.topComposite, SWT.PUSH );
        this.deletePresetButton.setText( Resources.deleteButtonLabel );
        
        this.deletePresetButton.addSelectionListener
        (
            new SelectionAdapter()
            {
                public void widgetSelected( final SelectionEvent e )
                {
                    handleDeletePreset();
                }
            }
        );
        
        final int width 
            = Math.max( getPreferredWidth( this.savePresetButton ), 
                        getPreferredWidth( this.deletePresetButton ) ) + 15;
                        
        this.savePresetButton.setLayoutData( gdwhint( gd(), width ) );
        this.deletePresetButton.setLayoutData( gdwhint( gd(), width ) );
        
        this.sform1 = new SashForm( this.topComposite, SWT.VERTICAL | SWT.SMOOTH );
        this.sform1.setLayoutData( gdhspan( gdfill(), 4 ) );
        
        this.sform2 = new SashForm( this.sform1, SWT.HORIZONTAL | SWT.SMOOTH );
        this.sform2.setLayoutData( gdhspan( gdfill(), 4 ) );
        
        this.treeViewer = new CheckboxTreeViewer( this.sform2, SWT.BORDER );
        this.tree = this.treeViewer.getTree();
        
        this.tree.setHeaderVisible( true );
        
        this.treeViewer.setContentProvider( new ContentProvider() );
        this.treeViewer.setSorter( new Sorter() );
        
        this.colFacet = new TreeViewerColumn( this.treeViewer, SWT.NONE );
        this.colFacet.getColumn().setText( Resources.facetColumnLabel );
        this.colFacet.getColumn().setResizable( true );
        this.colFacet.setLabelProvider( new FacetColumnLabelProvider() );
        
        if( this.settings.get( CW_FACET ) == null )
        {
            this.settings.put( CW_FACET, computeDefaultFacetColumnWidth() );
        }
        
        this.colFacet.getColumn().setWidth( this.settings.getInt( CW_FACET ) );
        
        this.colFacet.getColumn().addListener
        (
            SWT.Resize,
            new Listener()
            {
                public void handleEvent( final Event event )
                {
                    FacetsSelectionPanel.this.settings.put( CW_FACET, FacetsSelectionPanel.this.colFacet.getColumn().getWidth() );
                }
            }
        );

        this.colVersion = new TreeViewerColumn( this.treeViewer, SWT.NONE );
        this.colVersion.getColumn().setText( Resources.versionColumnLabel );
        this.colVersion.getColumn().setResizable( true );
        this.colVersion.setLabelProvider( new FacetVersionColumnLabelProvider() );
        this.colVersion.setEditingSupport( new FacetVersionColumnEditingSupport( this.treeViewer ) );
        
        if( this.settings.get( CW_VERSION ) == null )
        {
            this.settings.put( CW_VERSION, computeDefaultVersionColumnWidth() );
        }

        this.colVersion.getColumn().setWidth( this.settings.getInt( CW_VERSION ) );
        
        this.colVersion.getColumn().addListener
        (
            SWT.Resize,
            new Listener()
            {
                public void handleEvent( final Event event )
                {
                    FacetsSelectionPanel.this.settings.put( CW_VERSION, FacetsSelectionPanel.this.colVersion.getColumn().getWidth() );
                }
            }
        );
        
        this.popupMenu = new Menu( getShell(), SWT.POP_UP );
        
        this.popupMenuChangeVersion = new MenuItem( this.popupMenu, SWT.PUSH );
        this.popupMenuChangeVersion.setText( Resources.changeVersionMenuItem );

        this.popupMenuChangeVersion.addSelectionListener
        (
            new SelectionAdapter()
            {
                public void widgetSelected( final SelectionEvent e )
                {
                    handleChangeVersionMenuSelected();
                }
            }
        );
        
        this.popupMenuLockUnlock = new MenuItem( this.popupMenu, SWT.PUSH );
        
        this.popupMenuLockUnlock.addSelectionListener
        (
            new SelectionAdapter()
            {
                public void widgetSelected( final SelectionEvent e )
                {
                    handleFacetLockUnlock();
                }
            }
        );

        new FacetToolTip( this.tree );
        new CategoryToolTip( this.tree );
        this.fixedFacetToolTip = new FixedFacetToolTip( this.tree );
        
        this.treeViewer.setInput( new Object() );

        this.treeViewer.addSelectionChangedListener
        (
            new ISelectionChangedListener()
            {
                public void selectionChanged( final SelectionChangedEvent e )
                {
                    FacetsSelectionPanel.this.handleSelectionChangedEvent();
                }
            }
        );
        
        this.treeViewer.addCheckStateListener
        (
            new ICheckStateListener()
            {
                public void checkStateChanged( final CheckStateChangedEvent e )
                {
                    FacetsSelectionPanel.this.handleCheckStateChanged( e );
                }
            }
        );

        this.tree.addListener
        (
            SWT.PaintItem,
            new Listener()
            {
                public void handleEvent( final Event event )
                {
                    handlePaintItemEvent( event );
                }
            }
        );
        
        this.tree.addListener
        (
            SWT.MouseDown,
            new Listener()
            {
                public void handleEvent( final Event event )
                {
                    handleMouseDownEvent( event );
                }
            }
        );
        
        final TabFolder tabFolder = new TabFolder( this.sform2, SWT.NONE );
        tabFolder.setLayoutData( gdhhint( gdhfill(), 80 ) );

        this.detailsPanel = new DetailsPanel( tabFolder, this );
        this.detailsTabItem = new TabItem( tabFolder, SWT.NULL );
        this.detailsTabItem.setControl( this.detailsPanel );
        this.detailsTabItem.setText( Resources.detailsTabLabel );

        this.runtimesPanel = new RuntimesPanel( tabFolder, this.fpjwc );
        this.runtimesTabItem = new TabItem( tabFolder, SWT.NULL );
        this.runtimesTabItem.setControl( this.runtimesPanel );
        this.runtimesTabItem.setText( Resources.runtimesTabLabel );
        
        this.runtimesPanel.addListener
        (
            SWT.Resize,
            new Listener()
            {
                public void handleEvent( final Event event )
                {
                    final int[] weights = FacetsSelectionPanel.this.sform1.getWeights();
                    FacetsSelectionPanel.this.settings.put( SASH1W1, weights[ 0 ] );
                    FacetsSelectionPanel.this.settings.put( SASH1W2, weights[ 1 ] );
                }
            }
        );

        this.problemsView = new TableViewer( this.sform1, SWT.BORDER );
        this.problemsView.setContentProvider( new ProblemsContentProvider() );
        this.problemsView.setLabelProvider( new ProblemsLabelProvider() );
        this.problemsView.setInput( new Object() );

        this.problemsView.getTable().addListener
        (
            SWT.Resize,
            new Listener()
            {
                public void handleEvent( final Event event )
                {
                    final int[] weights = FacetsSelectionPanel.this.sform2.getWeights();
                    FacetsSelectionPanel.this.settings.put( SASH2W1, weights[ 0 ] );
                    FacetsSelectionPanel.this.settings.put( SASH2W2, weights[ 1 ] );
                }
            }
        );
        
        if( this.settings.get( SASH1W1 ) == null ) this.settings.put( SASH1W1, 70 );
        if( this.settings.get( SASH1W2 ) == null ) this.settings.put( SASH1W2, 30 );
        if( this.settings.get( SASH2W1 ) == null ) this.settings.put( SASH2W1, 60 );
        if( this.settings.get( SASH2W2 ) == null ) this.settings.put( SASH2W2, 40 );
        
        final int[] weights1
            = new int[] { this.settings.getInt( SASH1W1 ),
                          this.settings.getInt( SASH1W2 ) };

        this.sform1.setWeights( weights1 );

        final int[] weights2
            = new int[] { this.settings.getInt( SASH2W1 ),
                          this.settings.getInt( SASH2W2 ) };

        this.sform2.setWeights( weights2 );
        
        addDisposeListener
        (
            new DisposeListener()
            {
                public void widgetDisposed( final DisposeEvent e )
                {
                    handleDisposeEvent();
                }
            }
        );
        
        Dialog.applyDialogFont( parent );
        
        // Setup runtime lifecycle listener.
        
        this.runtimeLifecycleListener = new IRuntimeLifecycleListener()
        {
            public void handleEvent( final IRuntimeLifecycleEvent event )
            {
                handleValidationProblemsChangedEvent();
            }
        };
        
        RuntimeManager.addListener( this.runtimeLifecycleListener, 
                                    IRuntimeLifecycleEvent.Type.VALIDATION_STATUS_CHANGED );
        
        // Bind to the model.
        
        addWorkingCopyListener
        (
            new IFacetedProjectListener()
            {
                public void handleEvent( final IFacetedProjectEvent event )
                {
                    handleProjectFacetsChangedEvent( event );
                }
            },
            IFacetedProjectEvent.Type.PROJECT_FACETS_CHANGED
        );
        
        handleProjectFacetsChangedEvent( null );
        
        addWorkingCopyListener
        (
            new IFacetedProjectListener()
            {
                public void handleEvent( final IFacetedProjectEvent event )
                {
                    handleValidationProblemsChangedEvent();
                }
            },
            IFacetedProjectEvent.Type.VALIDATION_PROBLEMS_CHANGED,
            IFacetedProjectEvent.Type.PROJECT_MODIFIED
        );
        
        handleValidationProblemsChangedEvent();
        
        addWorkingCopyListener
        ( 
            new IFacetedProjectListener()
            {
                public void handleEvent( final IFacetedProjectEvent event )
                {
                    handleSelectedPresetChangedEvent();
                }
            },
            IFacetedProjectEvent.Type.SELECTED_PRESET_CHANGED
        );

        ModifyFacetedProjectWizard.syncWithPresetsModel( this.fpjwc, this.presetsCombo );
        
        addWorkingCopyListener
        ( 
            new IFacetedProjectListener()
            {
                public void handleEvent( final IFacetedProjectEvent event )
                {
                    handleModelChangedEvent( event );
                }
            },
            IFacetedProjectEvent.Type.FIXED_FACETS_CHANGED, 
            IFacetedProjectEvent.Type.SELECTED_PRESET_CHANGED,
            IFacetedProjectEvent.Type.TARGETED_RUNTIMES_CHANGED
        );
        
        // Select the first item in the table.
        
        if( this.tree.getItemCount() > 0 )
        {
            final TreeItem firstItem = this.tree.getItem( 0 );
            this.treeViewer.setSelection( new StructuredSelection( firstItem.getData() ) );
        }
        
        handleSelectionChangedEvent();
    }
    
    public IFacetedProjectWorkingCopy getFacetedProjectWorkingCopy()
    {
        return this.fpjwc;
    }
    
    public boolean isSelectionValid()
    {
        return ( this.fpjwc.validate().getSeverity() != IStatus.ERROR );
    }
    
    public boolean setFocus()
    {
        return this.tree.setFocus();
    }
    
    public void addSelectionChangedListener( final ISelectionChangedListener listener )
    {
        this.selectionListeners.add( listener );
    }

    public void removeSelectionChangedListener( final ISelectionChangedListener listener )
    {
        this.selectionListeners.remove( listener );
    }

    public ISelection getSelection()
    {
        if( this.selection != null )
        {
            return new StructuredSelection( this.selection );
        }
        else
        {
            return new StructuredSelection( new Object[ 0 ] );
        }
    }

    public void setSelection( final ISelection selection )
    {
        throw new UnsupportedOperationException();
    }

    private void notifySelectionChangedListeners()
    {
        final SelectionChangedEvent event = new SelectionChangedEvent( this, getSelection() );

        for( ISelectionChangedListener listener : this.selectionListeners )
        {
            listener.selectionChanged( event );
        }
    }
    
    private ImageRegistry getImageRegistry()
    {
        return this.imageRegistry;
    }
    
    public Image getImage( final IProjectFacet facet,
                           final boolean showDecorations )
    {
        final boolean isFixed = getFacetedProjectWorkingCopy().isFixedProjectFacet( facet );
        final String id = ( isFixed && showDecorations ? "F:" : "f:" ) + facet.getId(); //$NON-NLS-1$ //$NON-NLS-2$
        
        Image image = getImageRegistry().get( id );
        
        if( image == null )
        {
            final IDecorationsProvider decprov
                = (IDecorationsProvider) facet.getAdapter( IDecorationsProvider.class );
            
            ImageDescriptor imgdesc = decprov.getIcon();
            
            if( isFixed && showDecorations )
            {
                imgdesc = new FixedFacetImageDescriptor( imgdesc );
            }
            
            getImageRegistry().put( id, imgdesc );
            image = getImageRegistry().get( id );
        }

        return image;
    }
    
    public Image getImage( final ICategory category )
    {
        final String id = "c:" + category.getId(); //$NON-NLS-1$
        
        Image image = getImageRegistry().get( id );
        
        if( image == null )
        {
            final IDecorationsProvider decprov
                = (IDecorationsProvider) category.getAdapter( IDecorationsProvider.class );
            
            final ImageDescriptor imgdesc = decprov.getIcon();
            
            getImageRegistry().put( id, imgdesc );
            image = getImageRegistry().get( id );
        }

        return image;
        
    }

    private void refresh()
    {
        // Somehow the checked state of nested items gets lost when a refresh
        // is performed, so we have to do this workaround.
        
        final Object[] checked = this.treeViewer.getCheckedElements();
        this.treeViewer.refresh();
        this.treeViewer.setCheckedElements( checked );
    }
    
    public void setCategoryExpandedState( final ICategory category,
                                          final boolean expanded )
    {
        this.treeViewer.setExpandedState( category, expanded );
    }
    
    public boolean getShowToolTips()
    {
        return this.showToolTips;
    }
    
    public void setShowToolTips( final boolean showToolTips )
    {
        this.showToolTips = showToolTips;
    }
    
    private void refreshCategoryState( final ICategory category )
    {
        if( category == null )
        {
            return;
        }
        
        int available = 0;
        int selected = 0;

        for( IProjectFacet f : category.getProjectFacets() )
        {
            if( this.fpjwc.isFacetAvailable( f ) )
            {
                available++;
            }
            
            if( this.fpjwc.hasProjectFacet( f ) )
            {
                selected++;
            }
        }

        if( selected == 0 )
        {
            this.treeViewer.setChecked( category, false );
            this.treeViewer.setGrayed( category, false );
        }
        else if( selected == available )
        {
            this.treeViewer.setChecked( category, true );
            this.treeViewer.setGrayed( category, false );
        }
        else
        {
            this.treeViewer.setGrayChecked( category, true );
        }
    }
    
    private void addWorkingCopyListener( final IFacetedProjectListener listener,
                                         final IFacetedProjectEvent.Type... types )
    {
        this.fpjwc.addListener( listener, types );
        this.registeredWorkingCopyListeners.add( listener );
    }

    public IProjectFacet getSelectedProjectFacet()
    {
        final IProjectFacetVersion fv = getSelectedProjectFacetVersion();
        
        if( fv != null )
        {
            return fv.getProjectFacet();
        }
        
        return null;
    }
    
    public IProjectFacetVersion getSelectedProjectFacetVersion()
    {
        if( this.selection != null && this.selection instanceof IProjectFacetVersion )
        {
            return (IProjectFacetVersion) this.selection;
        }
        
        return null;
    }
    
    private IProjectFacetVersion getSelectedVersion( final IProjectFacet f )
    {
        final Set<IProjectFacetVersion> availableVersions = this.fpjwc.getAvailableVersions( f );
        
        if( availableVersions.isEmpty() )
        {
            throw new IllegalStateException();
        }
        
        IProjectFacetVersion selectedVersion = this.fpjwc.getProjectFacetVersion( f );
        
        if( selectedVersion == null )
        {
            selectedVersion = this.selectedVersions.get( f );

            if( selectedVersion == null )
            {
                selectedVersion = f.getDefaultVersion();
            }
            
            if( ! availableVersions.contains( selectedVersion ) )
            {
                selectedVersion = this.fpjwc.getHighestAvailableVersion( f );
            }
        }
        
        this.selectedVersions.put( f, selectedVersion );
        
        return selectedVersion;
    }
    
    private void setSelectedVersion( final IProjectFacet f,
                                     final IProjectFacetVersion fv )
    {
        if( this.fpjwc.getProjectFacetVersion( f ) != null )
        {
            this.fpjwc.changeProjectFacetVersion( fv );
        }
        
        this.selectedVersions.put( f, fv );
        
        if( f == this.getSelectedProjectFacet() )
        {
            this.selection = fv;
            notifySelectionChangedListeners();
        }
    }
    
    private void handleSelectionChangedEvent()
    {
        Object selection = ( (IStructuredSelection) this.treeViewer.getSelection() ).getFirstElement();

        if( selection != null && selection instanceof IProjectFacet )
        {
            selection = getSelectedVersion( (IProjectFacet ) selection );
        }
        
        if( selection != this.selection )
        {
            this.selection = selection;

            notifySelectionChangedListeners();
            updatePopupMenu();
        }
    }
    
    private void handleCheckStateChanged( final CheckStateChangedEvent event )
    {
        final Object el = event.getElement();
        final boolean checked = event.getChecked();
        
        if( el instanceof IProjectFacet )
        {
            final IProjectFacet f = (IProjectFacet) el;
            
            if( this.fpjwc.getFixedProjectFacets().contains( f ) )
            {
                if( ! checked )
                {
                    this.treeViewer.setChecked( el, true );
                    
                    final String msg 
                        = NLS.bind( Resources.couldNotDeselectFixedFacetMessage, f.getLabel() );                    

                    this.fixedFacetToolTip.setMessage( msg );
                    
                    final Point cursorLocation = getDisplay().getCursorLocation();
                    this.fixedFacetToolTip.show( this.tree.toControl( cursorLocation ) );
                }
                
                return;
            }
            
            if( checked )
            {
                this.fpjwc.addProjectFacet( getSelectedVersion( f ) );
            }
            else
            {
                this.fpjwc.removeProjectFacet( f );
            }
            
            refreshCategoryState( f.getCategory() );
        }
        else
        {
            final ContentProvider cp
                = (ContentProvider) this.treeViewer.getContentProvider();

            final Set<IProjectFacetVersion> facets
                = new HashSet<IProjectFacetVersion>( this.fpjwc.getProjectFacets() );
                
            final Object[] children = cp.getChildren( el );
            int selected = 0;
            
            for( Object child : children )
            {
                final IProjectFacet f = (IProjectFacet) child;
                
                if( ! this.fpjwc.getFixedProjectFacets().contains( f ) )
                {
                    final IProjectFacetVersion fv = getSelectedVersion( f );
                    
                    if( checked )
                    {
                        facets.add( fv );
                    }
                    else
                    {
                        facets.remove( fv );
                    }
                    
                    this.treeViewer.setChecked( f, checked );
                }
                
                if( this.fpjwc.hasProjectFacet( f ) )
                {
                    selected++;
                }
            }
            
            if( selected == 0 || selected == children.length )
            {
                this.treeViewer.setGrayed( el, false );
            }
            else
            {
                this.treeViewer.setGrayChecked( el, true );
            }
            
            this.fpjwc.setProjectFacets( facets );
        }

        this.fpjwc.setSelectedPreset( null );
        
        updatePopupMenu();
    }

    private void handleMouseDownEvent( final Event event )
    {
        handleMouseDownEventHelper( event, this.tree.getItems() );
    }
    
    private boolean handleMouseDownEventHelper( final Event event,
                                                final TreeItem[] items )
    {
        for( TreeItem item : items )
        {
            if( item.getBounds( 1 ).contains( event.x, event.y ) )
            {
                final TreeItem[] newSelection = new TreeItem[] { item };
                
                if( ! Arrays.equals( this.tree.getSelection(), newSelection ) )
                {
                    this.tree.setSelection( new TreeItem[] { item } );
                    this.treeViewer.editElement( item.getData(), 1 );
                }
                
                return true;
            }
            else if( handleMouseDownEventHelper( event, item.getItems() ) )
            {
                return true;
            }
        }
        
        return false;
    }
    
    private void handlePaintItemEvent( final Event event )
    {
        final TreeItem item = (TreeItem) event.item;
        final Object itemData = item.getData();

        if( itemData instanceof IProjectFacet && event.index == 1 )
        {
            final IProjectFacet f = (IProjectFacet) itemData;
            
            if( this.fpjwc.getAvailableVersions( f ).size() > 1 )
            {
                final Image arrowImage = getImageRegistry().get( IMG_DOWN_ARROW );
                final Rectangle arrowImageBounds = arrowImage.getBounds();
                
                final int columnWidth = this.colVersion.getColumn().getWidth();
                final int itemHeight = this.tree.getItemHeight();
                
                int x, y;
                
                x = event.x + columnWidth - arrowImageBounds.width - 10;
                y = event.y;
                event.gc.fillRectangle( x, y, arrowImageBounds.width + 10, itemHeight );
                
                y = event.y + ( itemHeight - arrowImageBounds.height ) / 2;
                event.gc.drawImage( arrowImage, x, y );
            }
        }
    }
    
    private void handleDisposeEvent()
    {
        this.imageRegistry.dispose();
        
        for( IFacetedProjectListener listener : this.registeredWorkingCopyListeners )
        {
            this.fpjwc.removeListener( listener );
        }
        
        RuntimeManager.removeListener( this.runtimeLifecycleListener );
    }
    
    private void handleSavePreset()
    {
        final Set<IProjectFacetVersion> facets = this.fpjwc.getProjectFacets();
        final IPreset preset = SavePresetDialog.showDialog( getShell(), facets );
        
        if( preset != null )
        {
            this.fpjwc.setSelectedPreset( preset.getId() );
        }
    }
    
    private void handleDeletePreset()
    {
        final IPreset preset = this.fpjwc.getSelectedPreset();
        this.fpjwc.setSelectedPreset( null );
        ProjectFacetsManager.deletePreset( preset );
    }
    
    private void handleProjectFacetsChangedEvent( final IFacetedProjectEvent event )
    {
        final Set<ICategory> affectedCategories = new HashSet<ICategory>();
        
        if( event != null )
        {
            final IFacetedProjectWorkingCopy fpjwc = event.getWorkingCopy();
            
            final IProjectFacetsChangedEvent evt
                = (IProjectFacetsChangedEvent) event;
            
            for( IProjectFacetVersion fv : evt.getAllAffectedFacets())
            {
                final IProjectFacet f = fv.getProjectFacet();
                final boolean checked = fpjwc.hasProjectFacet( fv );
                this.treeViewer.setChecked( f, checked );
                this.treeViewer.update( f, null );
                
                final ICategory category = f.getCategory();
                
                if( category != null )
                {
                    affectedCategories.add( category );
                }
            }
        }
        else
        {
            final List<IProjectFacet> facets = new ArrayList<IProjectFacet>();
            
            for( IProjectFacetVersion fv : this.fpjwc.getProjectFacets() )
            {
                facets.add( fv.getProjectFacet() );
            }
            
            this.treeViewer.setCheckedElements( facets.toArray() );
            
            for( IProjectFacet facet : this.fpjwc.getAvailableFacets().keySet() )
            {
                final ICategory category = facet.getCategory();
                
                if( category != null )
                {
                    affectedCategories.add( category );
                }
            }
            
            this.treeViewer.update( this.fpjwc.getAvailableFacets().keySet().toArray(), null );
        }

        for( ICategory category : affectedCategories )
        {
            refreshCategoryState( category );
        }
    }
    
    private void handleValidationProblemsChangedEvent()
    {
        if( ! Thread.currentThread().equals( getDisplay().getThread() ) )
        {
            final Runnable uiRunnable = new Runnable()
            {
                public void run()
                {
                    handleValidationProblemsChangedEvent();
                }
            };
            
            getDisplay().asyncExec( uiRunnable );
            
            return;
        }
        
        this.problemsView.refresh();

        if( getFilteredProblems().length == 0 )
        {
            if( this.sform1.getMaximizedControl() == null )
            {
                this.sform1.setMaximizedControl( this.sform2 );
            }
        }
        else
        {
            if( this.sform1.getMaximizedControl() != null )
            {
                this.sform1.setMaximizedControl( null );
            }
        }
    }
    
    private void handleSelectedPresetChangedEvent()
    {
        final IPreset preset = this.fpjwc.getSelectedPreset();
        
        if( preset == null )
        {
            this.savePresetButton.setEnabled( true );
            this.deletePresetButton.setEnabled( false );
        }
        else
        {
            this.savePresetButton.setEnabled( false );
            this.deletePresetButton.setEnabled( preset.getType() == IPreset.Type.USER_DEFINED );
        }
    }
    
    private void handleModelChangedEvent( final IFacetedProjectEvent event )
    {
        switch( event.getType() )
        {
            case FIXED_FACETS_CHANGED:
            case TARGETED_RUNTIMES_CHANGED:
            {
                final Runnable runnable = new Runnable()
                {
                    public void run()
                    {
                        refresh();
                    }
                };
                
                runOnDisplayThread( getDisplay(), runnable );
                
                break;
            }
        }
    }
    
    private void handleChangeVersionMenuSelected()
    {
        final IProjectFacet f = getSelectedProjectFacet();
        final IProjectFacetVersion fv = getSelectedVersion( f );
        final SortedSet<IProjectFacetVersion> versions = this.fpjwc.getAvailableVersions( f );
        
        final IProjectFacetVersion newVersion
            = ChangeFacetVersionDialog.showDialog( getShell(), f, fv, versions );
            
        if( newVersion != null )
        {
            this.fpjwc.changeProjectFacetVersion( newVersion );
        }
    }
    
    private void handleFacetLockUnlock()
    {
        final IProjectFacet f = getSelectedProjectFacet();
        
        final Set<IProjectFacet> fixedFacets 
            = new HashSet<IProjectFacet>( this.fpjwc.getFixedProjectFacets() );
        
        if( fixedFacets.contains( f ) )
        {
            fixedFacets.remove( f );
        }
        else
        {
            fixedFacets.add( f );
        }
        
        this.fpjwc.setFixedProjectFacets( fixedFacets );
        
        updatePopupMenu();
    }
    
    private void updatePopupMenu()
    {
        if( this.selection instanceof IProjectFacetVersion )
        {
            this.tree.setMenu( this.popupMenu );

            final IProjectFacet f = ( (IProjectFacetVersion) this.selection ).getProjectFacet();
            
            if( this.fpjwc.isFixedProjectFacet( f ) )
            {
                this.popupMenuLockUnlock.setText( Resources.unlockMenuItem );
            }
            else
            {
                this.popupMenuLockUnlock.setText( Resources.lockMenuItem );
            }
            
            this.popupMenuLockUnlock.setEnabled( this.fpjwc.hasProjectFacet( f ) );
            
            final int numAvailableVersions = this.fpjwc.getAvailableVersions( f ).size();
            this.popupMenuChangeVersion.setEnabled( numAvailableVersions > 1 );
        }
        else
        {
            this.tree.setMenu( null );
        }
    }
    
    private TreeItem getTreeItem( final int x,
                                  final int y )
    {
        return getTreeItemHelper( x, y, this.tree.getItems() );
    }
    
    private static TreeItem getTreeItemHelper( final int x,
                                               final int y,
                                               final TreeItem[] items )
    {
        for( TreeItem item : items )
        {
            if( item.getBounds().contains( x, y ) )
            {
                return item;
            }
            
            final TreeItem res = getTreeItemHelper( x, y, item.getItems() );
            
            if( res != null )
            {
                return res;
            }
        }
        
        return null;
    }
    
    private int computeDefaultFacetColumnWidth()
    {
        final GC gc = new GC( this.getDisplay() );
        int maxFacetLabelWidth = 0;
        
        try
        {
            gc.setFont( this.tree.getFont() );
            
            for( IProjectFacet f : ProjectFacetsManager.getProjectFacets() )
            {
                maxFacetLabelWidth = max( maxFacetLabelWidth, gc.textExtent( f.getLabel() ).x );
            }
        }
        finally
        {
            gc.dispose();
        }
        
        return max( maxFacetLabelWidth + 100, 200 );
    }

    private int computeDefaultVersionColumnWidth()
    {
        final GC gc = new GC( this.getDisplay() );
        int maxVersionStringWidth = 0;
        final int columnLabelWidth;
        
        try
        {
            gc.setFont( this.tree.getFont() );

            for( IProjectFacet f : ProjectFacetsManager.getProjectFacets() )
            {
                for( IProjectFacetVersion fv : f.getVersions() )
                {
                    final int textExtent = gc.textExtent( fv.getVersionString() ).x;
                    maxVersionStringWidth = max( maxVersionStringWidth, textExtent + 30 );
                }
            }

            columnLabelWidth = gc.textExtent( Resources.versionColumnLabel ).x + 30;
        }
        finally
        {
            gc.dispose();
        }
        
        return max( maxVersionStringWidth, columnLabelWidth );
    }
    
    private IStatus[] getFilteredProblems()
    {
        final IStatus[] unfiltered = this.fpjwc.validate().getChildren();
        boolean somethingToRemove = false;
        
        for( IStatus st : unfiltered )
        {
            if( st.getCode() == IFacetedProjectWorkingCopy.PROBLEM_PROJECT_NAME )
            {
                somethingToRemove = true;
                break;
            }
        }
        
        if( ! somethingToRemove )
        {
            return unfiltered;
        }
        
        final List<IStatus> filtered = new ArrayList<IStatus>();
        
        for( IStatus st : unfiltered )
        {
            if( st.getCode() != IFacetedProjectWorkingCopy.PROBLEM_PROJECT_NAME )
            {
                filtered.add( st );
            }
        }
        
        return filtered.toArray( new IStatus[ filtered.size() ] );
    }

    private final class ContentProvider

        implements ITreeContentProvider

    {
        public Object[] getElements( final Object element )
        {
            final IFacetedProjectWorkingCopy fpjwc = getFacetedProjectWorkingCopy();
            final List<Object> list = new ArrayList<Object>();
            final Set<ICategory> categories = ProjectFacetsManager.getCategories();

            for( ICategory cat : categories )
            {
                boolean visible = false;

                for( IProjectFacet f : cat.getProjectFacets() )
                {
                    if( ! fpjwc.getAvailableVersions( f ).isEmpty() )
                    {
                        visible = true;
                        break;
                    }
                }

                if( visible )
                {
                    list.add( cat );
                }
            }
            
            for( Map.Entry<IProjectFacet,SortedSet<IProjectFacetVersion>> entry 
                 : fpjwc.getAvailableFacets().entrySet() )
            {
                final IProjectFacet f = entry.getKey();
                final SortedSet<IProjectFacetVersion> availableVersions = entry.getValue();
                
                if( f.getCategory() == null && ! availableVersions.isEmpty() )
                {
                    list.add( f );
                }
            }

            return list.toArray();
        }

        public Object[] getChildren( final Object parent )
        {
            if( parent instanceof ICategory )
            {
                final IFacetedProjectWorkingCopy fpjwc = getFacetedProjectWorkingCopy();
                final ICategory category = (ICategory) parent;
                final List<IProjectFacet> facets = new ArrayList<IProjectFacet>();

                for( IProjectFacet f : category.getProjectFacets() )
                {
                    if( ! fpjwc.getAvailableVersions( f ).isEmpty() )
                    {
                        facets.add( f );
                    }
                }

                return facets.toArray();
            }
            else
            {
                return new Object[ 0 ];
            }
        }

        public Object getParent( final Object element )
        {
            if( element instanceof IProjectFacet )
            {
                final IProjectFacet f = (IProjectFacet) element;
                return f.getCategory();
            }
            else
            {
                return null;
            }
        }

        public boolean hasChildren( final Object element )
        {
            return ( element instanceof ICategory ) &&
                   ! ( (ICategory) element ).getProjectFacets().isEmpty();
        }

        public void dispose() { }

        public void inputChanged( final Viewer viewer,
                                  final Object oldObject,
                                  final Object newObject ) {}
    }

    private final class FacetColumnLabelProvider

        extends ColumnLabelProvider
    
    {
        @Override
        public String getText( final Object element )
        {
            if( element instanceof ICategory )
            {
                return ( (ICategory) element ).getLabel();
            }
            else
            {
                return ( (IProjectFacet) element ).getLabel();
            }
        }
    
        @Override
        public Image getImage( final Object element )
        {
            if( element instanceof IProjectFacet )
            {
                return FacetsSelectionPanel.this.getImage( (IProjectFacet) element, true );
            }
            else
            {
                return FacetsSelectionPanel.this.getImage( (ICategory) element );
            }
        }
    }

    private final class FacetVersionColumnLabelProvider

        extends ColumnLabelProvider

    {
        @Override
        public String getText( final Object element )
        {
            if( element instanceof IProjectFacet )
            {
                final ProjectFacet f = (ProjectFacet) element;
                
                if( ! f.isVersionHidden() )
                {
                    return getSelectedVersion( f ).getVersionString();
                }
            }
            
            return null;
        }
    }

    private final class FacetVersionColumnEditingSupport

        extends EditingSupport
    
    {
        private final ReadOnlyComboBoxCellEditor ceditor;
        private final IFacetedProjectWorkingCopy fpjwc;
        
        public FacetVersionColumnEditingSupport( final TreeViewer treeViewer )
        {
            super( treeViewer );
            this.ceditor = new ReadOnlyComboBoxCellEditor( treeViewer.getTree(), new String[ 0 ], SWT.DROP_DOWN | SWT.READ_ONLY );
            this.fpjwc = getFacetedProjectWorkingCopy();
        }
        
        @Override
        public boolean canEdit( final Object element )
        {
            return element instanceof IProjectFacet &&
                   this.fpjwc.getAvailableVersions( (IProjectFacet ) element ).size() > 1;
        }
        
        @Override
        protected CellEditor getCellEditor( final Object element )
        {
            final IProjectFacet f = (IProjectFacet) element;
            
            if( f == null )
            {
                throw new IllegalStateException();
            }
            
            final SortedSet<IProjectFacetVersion> versions = this.fpjwc.getAvailableVersions( f );
            final String[] verstrs = new String[ versions.size() ];
            Integer value = null;
            
            int i = 0;
            
            for( IProjectFacetVersion fv : versions )
            {
                verstrs[ i ] = fv.getVersionString();
                
                if( fv == getSelectedVersion( f ) )
                {
                    value = new Integer( i );
                }
                
                i++;
            }
            
            this.ceditor.setItems( verstrs );
            this.ceditor.setValue( value );
            
            return this.ceditor;
        }
    
        @Override
        public Object getValue( final Object element )
        {
            final IProjectFacet f = (IProjectFacet) element;
            int i = 0;
            
            for( IProjectFacetVersion fv : this.fpjwc.getAvailableVersions( f ) )
            {
                if( fv == getSelectedVersion( f ) )
                {
                    return new Integer( i );
                }
                
                i++;
            }
    
            return new IllegalStateException();
        }
    
        @Override
        public void setValue( final Object element,
                              final Object value )
        {
            final IProjectFacet f = (IProjectFacet) element;
            final int index = ( (Integer) value ).intValue();
    
            if( index != -1 )
            {
                int i = 0;
                
                for( IProjectFacetVersion fv : this.fpjwc.getAvailableVersions( f ) )
                {
                    if( i == index )
                    {
                        setSelectedVersion( f, fv );
                        FacetsSelectionPanel.this.treeViewer.update( f, null );
                        
                        break;
                    }
                    
                    i++;
                }
            }
        }
    }
    
    private static final class FixedFacetImageDescriptor 
    
        extends CompositeImageDescriptor 
        
    {
        private static final String OVERLAY_IMG_LOCATION
            = "images/lock.gif"; //$NON-NLS-1$
        
        private static final ImageData OVERLAY
            = FacetUiPlugin.getImageDescriptor( OVERLAY_IMG_LOCATION ).getImageData();
        
        private final ImageData base;
        private final Point size;
        
        public FixedFacetImageDescriptor( final ImageDescriptor base ) 
        {
            this.base = base.getImageData();
            this.size = new Point( this.base.width, this.base.height ); 
        }

        protected void drawCompositeImage( final int width, 
                                           final int height ) 
        {
            drawImage( this.base, 0, 0 );
            drawImage( OVERLAY, 0, height - OVERLAY.height );
        }

        protected Point getSize()
        {
            return this.size;
        }
    }
    
    private static final class Sorter

        extends ViewerSorter

    {
        public int compare( final Viewer viewer,
                            final Object a,
                            final Object b )
        {
            return getLabel( a ).compareToIgnoreCase( getLabel( b ) );
        }

        private static String getLabel( final Object obj )
        {
            if( obj instanceof IProjectFacet )
            {
                return ( (IProjectFacet) obj ).getLabel();
            }
            else
            {
                return ( (ICategory) obj ).getLabel();
            }
        }
    }
    
    private final class FacetToolTip
    
        extends HeaderToolTip
        
    {
        public FacetToolTip( final Control control )
        {
            super( control );
        }
        
        @Override
        protected final boolean shouldCreateToolTip( final Event event ) 
        {
            if( getShowToolTips() == false )
            {
                return false;
            }
            
            final TreeItem treeItem = getTreeItem( event.x, event.y );
            String description = null;
            
            if( treeItem != null && treeItem.getBounds( 0 ).contains( event.x, event.y ) )
            {
                final Object treeItemData = treeItem.getData();
                
                if( treeItemData instanceof IProjectFacet )
                {
                    description = ( (IProjectFacet) treeItemData ).getDescription();
                }
            }
            
            return ( description != null && description.trim().length() > 0 );
        }

        @Override
        protected String getToolTipTitle( final Event event )
        {
            final IProjectFacet f = (IProjectFacet) getTreeItem( event.x, event.y ).getData();
            return getSelectedVersion( f ).toString();
        }

        @Override
        protected Composite createContentArea( final Event event,
                                               final Composite parent )
        {
            final Display display = parent.getDisplay();
            
            final Composite composite = new Composite( parent, SWT.NONE );
            composite.setLayout( gl( 1 ) );
            composite.setBackground( display.getSystemColor( SWT.COLOR_INFO_BACKGROUND ) );
            
            final Label label = new Label( composite, SWT.WRAP );
            label.setLayoutData( gdfill() );
            label.setBackground( display.getSystemColor( SWT.COLOR_INFO_BACKGROUND ) );

            final IProjectFacet f = (IProjectFacet) getTreeItem( event.x, event.y ).getData();
            label.setText( f.getDescription() );
            
            return composite;
        }
    }

    private final class CategoryToolTip
    
        extends HeaderToolTip
        
    {
        public CategoryToolTip( final Control control )
        {
            super( control );
        }
        
        @Override
        protected final boolean shouldCreateToolTip( final Event event ) 
        {
            if( getShowToolTips() == false )
            {
                return false;
            }
            
            final TreeItem treeItem = getTreeItem( event.x, event.y );
            String description = null;
            
            if( treeItem != null && treeItem.getBounds( 0 ).contains( event.x, event.y ) )
            {
                final Object treeItemData = treeItem.getData();
                
                if( treeItemData instanceof ICategory )
                {
                    description = ( (ICategory) treeItemData ).getDescription();
                }
            }
            
            return ( description != null && description.trim().length() > 0 );
        }
    
        @Override
        protected String getToolTipTitle( final Event event )
        {
            return ( (ICategory) getTreeItem( event.x, event.y ).getData() ).getLabel();
        }
    
        @Override
        protected Composite createContentArea( final Event event,
                                               final Composite parent )
        {
            final Display display = parent.getDisplay();
            
            final Composite composite = new Composite( parent, SWT.NONE );
            composite.setLayout( gl( 1 ) );
            composite.setBackground( display.getSystemColor( SWT.COLOR_INFO_BACKGROUND ) );
            
            final Label label = new Label( composite, SWT.WRAP );
            label.setLayoutData( gdfill() );
            label.setBackground( display.getSystemColor( SWT.COLOR_INFO_BACKGROUND ) );
    
            final ICategory category = (ICategory) getTreeItem( event.x, event.y ).getData();
            label.setText( category.getDescription() );
            
            return composite;
        }
    }

    private final class FixedFacetToolTip
    
        extends BasicToolTip
        
    {
        private static final int FAKE_EVENT_TYPE = -9999;
        
        public FixedFacetToolTip( final Control control )
        {
            super( control );
            setPopupDelay( 0 );
        }
        
        public void show( final Point location )
        {
            // The JFace ToolTip class does not support alternative methods of tool tip activation.
            // An enhancement request https://bugs.eclipse.org/bugs/show_bug.cgi?id=174844 tracks
            // this issue. When that enhancement request has been resolved, this hacky 
            // implementation should be replaced with something more sensible.
            
            final Event fakeEvent = new Event();
            fakeEvent.type = FAKE_EVENT_TYPE;
            fakeEvent.x = location.x;
            fakeEvent.y = location.y;
            
            try
            {
                final Method method
                    = ToolTip.class.getDeclaredMethod( "toolTipCreate", Event.class ); //$NON-NLS-1$
                
                method.setAccessible( true );
                method.invoke( this, fakeEvent );
            }
            catch( Exception e )
            {
                FacetUiPlugin.log( e );
            }
        }
        
        @Override
        protected final boolean shouldCreateToolTip( final Event event ) 
        {
            return ( event.type == FAKE_EVENT_TYPE );
        }
    }
    
    private final class ProblemsContentProvider

        implements IStructuredContentProvider

    {
        public Object[] getElements( final Object element )
        {
            return getFilteredProblems();
        }

        public void inputChanged( final Viewer viewer,
                                  final Object oldObject,
                                  final Object newObject ) {}
        
        public void dispose() {}
    }

    private final class ProblemsLabelProvider

        implements ITableLabelProvider

    {
        public String getColumnText( final Object element,
                                     final int column )
        {
            return ( (IStatus) element ).getMessage();
        }

        public Image getColumnImage( final Object element,
                                     final int column )
        {
            final ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
            final String imageType;
            
            if( ( (IStatus) element ).getSeverity() == IStatus.ERROR )
            {
                imageType = ISharedImages.IMG_OBJS_ERROR_TSK;
            }
            else
            {
                imageType = ISharedImages.IMG_OBJS_WARN_TSK;
            }
            
            return sharedImages.getImage( imageType );
        }

        public boolean isLabelProperty( final Object obj,
                                        final String s )
        {
            return false;
        }

        public void dispose() {}
        public void addListener( final ILabelProviderListener listener ) {}
        public void removeListener( ILabelProviderListener listener ) {}
    }
    
    private static final class Resources
    
        extends NLS
        
    {
        public static String presetsLabel;
        public static String saveButtonLabel;
        public static String deleteButtonLabel;
        public static String facetColumnLabel;
        public static String versionColumnLabel;
        public static String couldNotDeselectFixedFacetMessage;
        public static String detailsTabLabel;
        public static String runtimesTabLabel;
        public static String lockMenuItem;
        public static String unlockMenuItem;
        public static String changeVersionMenuItem;
        
        static
        {
            initializeMessages( FacetsSelectionPanel.class.getName(), 
                                Resources.class );
        }
    }
    
}
