/******************************************************************************
 * 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 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.gdhalign;
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.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 java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.CompositeImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
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.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
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.runtime.IRuntime;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponent;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentType;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentVersion;
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.core.runtime.events.IValidationStatusChangedEvent;
import org.eclipse.wst.common.project.facet.core.runtime.internal.UnknownRuntime;
import org.eclipse.wst.common.project.facet.ui.IDecorationsProvider;
import org.eclipse.wst.common.project.facet.ui.IRuntimeComponentLabelProvider;
import org.eclipse.wst.common.project.facet.ui.internal.util.BasicToolTip;
import org.osgi.framework.Bundle;

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

public final class RuntimesPanel

    extends Composite

{
    private static final Object NO_RUNTIME_SELECTED_PLACEHOLDER = new Object();
    
    private final IFacetedProjectWorkingCopy fpjwc;
    private boolean showAllRuntimesSetting;
    private final CheckboxTableViewer runtimes;
    private final Button showAllRuntimesCheckbox;
    private final Button makePrimaryButton;
    private final Button newRuntimeButton;
    private final Label runtimeComponentsLabel;
    private final TableViewer runtimeComponents;
    private IRuntime currentPrimaryRuntime;
    private final List<IFacetedProjectListener> listeners;
    private Color colorGray;
    private final RuntimeValidationAssistant runtimeValidationAssistant;
    
    public RuntimesPanel( final Composite parent,
                          final IFacetedProjectWorkingCopy fpjwc )
    {
        super( parent, SWT.NONE );
        
        this.listeners = new ArrayList<IFacetedProjectListener>();
        
        addDisposeListener
        ( 
            new DisposeListener()
            {
                public void widgetDisposed( final DisposeEvent e )
                {
                    handleWidgetDisposed();
                }
            }
        );
        
        // Setup runtime validation assistant.
        
        this.runtimeValidationAssistant = new RuntimeValidationAssistant();
       
        // Bind to the data model.
        
        this.fpjwc = fpjwc;
        
        addDataModelListener
        ( 
            new IFacetedProjectListener()
            {
                public void handleEvent( final IFacetedProjectEvent event )
                {
                    handleAvailableRuntimesChanged();
                }
            },
            IFacetedProjectEvent.Type.AVAILABLE_RUNTIMES_CHANGED
        );
        
        addDataModelListener
        ( 
            new IFacetedProjectListener()
            {
                public void handleEvent( final IFacetedProjectEvent event )
                {
                    handleTargetableRuntimesChanged();
                }
            },
            IFacetedProjectEvent.Type.TARGETABLE_RUNTIMES_CHANGED
        );
        
        addDataModelListener
        ( 
            new IFacetedProjectListener()
            {
                public void handleEvent( final IFacetedProjectEvent event )
                {
                    handleTargetedRuntimesChanged();
                }
            },
            IFacetedProjectEvent.Type.TARGETED_RUNTIMES_CHANGED
        );
        
        addDataModelListener
        ( 
            new IFacetedProjectListener()
            {
                public void handleEvent( final IFacetedProjectEvent event )
                {
                    handlePrimaryRuntimeChanged();
                }
            },
            IFacetedProjectEvent.Type.PRIMARY_RUNTIME_CHANGED
        );
        
        this.showAllRuntimesSetting = false;

        // Initialize the colors.
        
        this.colorGray = new Color( null, 160, 160, 164 );

        // Layout the panel.
        
        final GridLayout layout = new GridLayout( 1, false );
        layout.marginHeight = 5;
        layout.marginWidth = 5;

        setLayout( layout );

        this.runtimes = CheckboxTableViewer.newCheckList( this, SWT.BORDER );
        this.runtimes.getTable().setLayoutData( gdfill() );
        this.runtimes.setContentProvider( new ContentProvider() );
        this.runtimes.setLabelProvider( new LabelProvider() );
        this.runtimes.setSorter( new Sorter() );
        this.runtimes.setInput( new Object() );
        
        new ValidationProblemToolTip( this.runtimes.getTable() );
        
        this.runtimes.addSelectionChangedListener
        (
            new ISelectionChangedListener()
            {
                public void selectionChanged( final SelectionChangedEvent e )
                {
                    handleRuntimeSelectionChanged();
                }
            }
        );
        
        this.runtimes.addCheckStateListener
        (
            new ICheckStateListener()
            {
                public void checkStateChanged( final CheckStateChangedEvent e )
                {
                    handleCheckStateChanged( e );
                }
            }
        );
        
        this.showAllRuntimesCheckbox = new Button( this, SWT.CHECK );
        this.showAllRuntimesCheckbox.setText( Resources.showAllRuntimes );
        this.showAllRuntimesCheckbox.setSelection( this.showAllRuntimesSetting );
        
        this.showAllRuntimesCheckbox.addSelectionListener
        (
            new SelectionAdapter()
            {
                public void widgetSelected( final SelectionEvent e )
                {
                    handleShowAllRuntimesSelected();
                }
            }
        );
        
        final Composite buttons = new Composite( this, SWT.NONE );
        buttons.setLayoutData( gdhalign( gd(), GridData.END ) );
        buttons.setLayout( glmargins( gl( 2 ), 0, 0 ) );
        
        GridData gd;
        
        this.makePrimaryButton = new Button( buttons, SWT.PUSH );
        this.makePrimaryButton.setText( Resources.makePrimaryLabel );
        gd = gdwhint( gd(), getPreferredWidth( this.makePrimaryButton ) + 15 );
        this.makePrimaryButton.setLayoutData( gd );
        this.makePrimaryButton.setEnabled( false );
        
        this.makePrimaryButton.addSelectionListener
        (
            new SelectionAdapter()
            {
                public void widgetSelected( final SelectionEvent e )
                {
                    handleMakePrimarySelected();
                }
            }
        );
        
        this.newRuntimeButton = new Button( buttons, SWT.PUSH );
        this.newRuntimeButton.setText( Resources.newRuntimeButtonLabel );
        gd = gdwhint( gd(), getPreferredWidth( this.newRuntimeButton ) + 15 );
        this.newRuntimeButton.setLayoutData( gd );

        this.newRuntimeButton.addSelectionListener
        (
            new SelectionAdapter()
            {
                public void widgetSelected( final SelectionEvent e )
                {
                    handleNewRuntimeButtonSelected();
                }
            }
        );
        
        this.runtimeComponentsLabel = new Label( this, SWT.NONE );
        this.runtimeComponentsLabel.setText( Resources.runtimeCompositionLabel );
        this.runtimeComponentsLabel.setLayoutData( gdhfill() );
        
        final Color infoBackgroundColor
            = parent.getDisplay().getSystemColor( SWT.COLOR_INFO_BACKGROUND );
        
        final Color infoForegroundColor
            = parent.getDisplay().getSystemColor( SWT.COLOR_INFO_FOREGROUND );
        
        this.runtimeComponents = new TableViewer( this, SWT.BORDER );
        this.runtimeComponents.getTable().setLayoutData( gdhhint( gdhfill(), 50 ) );
        this.runtimeComponents.getTable().setBackground( infoBackgroundColor );
        this.runtimeComponents.getTable().setForeground( infoForegroundColor );
        this.runtimeComponents.setContentProvider( new RuntimeComponentsContentProvider() );
        this.runtimeComponents.setLabelProvider( new RuntimeComponentsLabelProvider() );
        
        this.runtimeComponents.setInput( NO_RUNTIME_SELECTED_PLACEHOLDER );
        this.runtimeComponents.getTable().setEnabled( false );
        this.runtimeComponentsLabel.setEnabled( false );
        
        refresh();
        this.currentPrimaryRuntime = this.fpjwc.getPrimaryRuntime();
        
	    Dialog.applyDialogFont( parent );
    }
    
    public IFacetedProjectWorkingCopy getFacetedProjectWorkingCopy()
    {
        return this.fpjwc;
    }
    
    private void handleAvailableRuntimesChanged()
    {
        if( ! Thread.currentThread().equals( getDisplay().getThread() ) )
        {
            getDisplay().asyncExec
            ( 
                new Runnable()
                {
                    public void run()
                    {
                        handleAvailableRuntimesChanged();
                    }
                }
            );
            
            return;
        }
        
        if( this.showAllRuntimesSetting )
        {
            refresh();
        }
    }
    
    private void handleTargetableRuntimesChanged()
    {
        if( ! Thread.currentThread().equals( getDisplay().getThread() ) )
        {
            getDisplay().asyncExec
            ( 
                new Runnable()
                {
                    public void run()
                    {
                        handleTargetableRuntimesChanged();
                    }
                }
            );
            
            return;
        }
        
        refresh();
    }
    
    private void handleTargetedRuntimesChanged()
    {
        if( ! Thread.currentThread().equals( getDisplay().getThread() ) )
        {
            getDisplay().asyncExec
            ( 
                new Runnable()
                {
                    public void run()
                    {
                        handleTargetedRuntimesChanged();
                    }
                }
            );
            
            return;
        }
        
        final Set<IRuntime> targeted = this.fpjwc.getTargetedRuntimes();
        
        for( IRuntime r : this.fpjwc.getTargetableRuntimes() )
        {
            if( targeted.contains( r ) )
            {
                if( ! this.runtimes.getChecked( r ) )
                {
                    this.runtimes.setChecked( r, true );
                }
            }
            else
            {
                if( this.runtimes.getChecked( r ) )
                {
                    this.runtimes.setChecked( r, false );
                }
            }
        }
    }
    
    private void handlePrimaryRuntimeChanged()
    {
        if( ! Thread.currentThread().equals( getDisplay().getThread() ) )
        {
            getDisplay().asyncExec
            ( 
                new Runnable()
                {
                    public void run()
                    {
                        handlePrimaryRuntimeChanged();
                    }
                }
            );
            
            return;
        }
        
        if( this.currentPrimaryRuntime != null )
        {
            this.runtimes.update( this.currentPrimaryRuntime, null );
        }
        
        this.currentPrimaryRuntime = this.fpjwc.getPrimaryRuntime();
        
        if( this.currentPrimaryRuntime != null )
        {
            this.runtimes.update( this.currentPrimaryRuntime, null );
        }
    }
    
    private void handleCheckStateChanged( final CheckStateChangedEvent e )
    {
        final IRuntime runtime = (IRuntime) e.getElement();
        
        if( ! getFacetedProjectWorkingCopy().getTargetableRuntimes().contains( runtime ) &&
            ! ( runtime instanceof UnknownRuntime ) && e.getChecked() )
        {
            this.runtimes.setChecked( runtime, false );
            return;
        }
        
        if( e.getChecked() )
        {
            this.fpjwc.addTargetedRuntime( runtime );
        }
        else
        {
            this.fpjwc.removeTargetedRuntime( runtime );
        }
    }
    
    private void handleRuntimeSelectionChanged()
    {
        final IRuntime r = getSelection();
        
        if( r == null )
        {
            if( this.runtimeComponents.getInput() != null )
            {
                this.runtimeComponentsLabel.setEnabled( false );
                this.runtimeComponents.getTable().setEnabled( false );
                this.runtimeComponents.setInput( NO_RUNTIME_SELECTED_PLACEHOLDER );
            }
        }
        else
        {
            if( this.runtimeComponents.getInput() == null ||
                ! this.runtimeComponents.getInput().equals( r ) )
            {
                this.runtimeComponentsLabel.setEnabled( true );
                this.runtimeComponents.getTable().setEnabled( true );
                this.runtimeComponents.setInput( r );
            }
            
            if( this.runtimes.getChecked( r ) && 
                this.fpjwc.getPrimaryRuntime() != null && 
                ! this.fpjwc.getPrimaryRuntime().equals( r ) &&
                ( this.fpjwc.getTargetableRuntimes().contains( r ) || r instanceof UnknownRuntime ) )
            {
                this.makePrimaryButton.setEnabled( true );
            }
            else
            {
                this.makePrimaryButton.setEnabled( false );
            }
        }
    }
    
    private void handleShowAllRuntimesSelected()
    {
        this.showAllRuntimesSetting 
            = this.showAllRuntimesCheckbox.getSelection();
        
        refresh();
    }
    
    private void handleMakePrimarySelected()
    {
        this.fpjwc.setPrimaryRuntime( getSelection() );
    }
    
    @SuppressWarnings( "unchecked" )
    private void handleNewRuntimeButtonSelected()
    {
        final String SERVER_UI_PLUGIN_ID = "org.eclipse.wst.server.ui"; //$NON-NLS-1$
        final String CLASS_NAME = "org.eclipse.wst.server.ui.internal.ServerUIPlugin"; //$NON-NLS-1$
        final String METHOD_NAME = "showNewRuntimeWizard"; //$NON-NLS-1$
        
        final Bundle serverUiBundle = Platform.getBundle( SERVER_UI_PLUGIN_ID );
        
        if( serverUiBundle == null )
        {
            this.newRuntimeButton.setEnabled( false );
            return;
        }

        try
        {
            final Class serverUiPluginClass = serverUiBundle.loadClass( CLASS_NAME );
            
            final Method method
                = serverUiPluginClass.getMethod( METHOD_NAME, Shell.class, String.class );
            
            final Object result = method.invoke( null, getShell(), null );
            
            if( result.equals( true ) )
            {
                final Thread refreshThread = new Thread()
                {
                    public void run()
                    {
                        getFacetedProjectWorkingCopy().refreshTargetableRuntimes();
                    }
                };
                
                refreshThread.start();
            }
        }
        catch( Exception e )
        {
            FacetUiPlugin.log( e );
        }
    }

    private void handleWidgetDisposed()
    {
        removeDataModelListeners();
        this.colorGray.dispose();
        this.runtimeValidationAssistant.dispose();
    }
    
    private void handleRuntimeValidationResultChanged()
    {
        final Runnable uiRunnable = new Runnable()
        {
            public void run()
            {
                for( TableItem item : RuntimesPanel.this.runtimes.getTable().getItems() )
                {
                    RuntimesPanel.this.runtimes.update( item.getData(), null );
                }
            }
        };
        
        getDisplay().syncExec( uiRunnable );
    }
    
    private void refresh()
    {
        this.runtimes.refresh();

        final Set<IRuntime> untargetable = new HashSet<IRuntime>( RuntimeManager.getRuntimes() );
        untargetable.removeAll( this.fpjwc.getTargetableRuntimes() );
        
        this.runtimes.setCheckedElements( this.fpjwc.getTargetedRuntimes().toArray() );
    }
    
    private IRuntime getSelection()
    {
        final IStructuredSelection ssel 
            = (IStructuredSelection) this.runtimes.getSelection();
        
        if( ssel.isEmpty() )
        {
            return null;
        }
        else
        {
            return (IRuntime) ssel.getFirstElement();
        }
    }
    
    private void addDataModelListener( final IFacetedProjectListener listener,
                                       final IFacetedProjectEvent.Type... types )
    {
        this.fpjwc.addListener( listener, types );
        this.listeners.add( listener );
    }
    
    private void removeDataModelListeners()
    {
        for( IFacetedProjectListener listener : this.listeners )
        {
            this.fpjwc.removeListener( listener );
        }
    }
    
    private TableItem getTableItem( final int x,
                                    final int y )
    {
        for( TableItem item : this.runtimes.getTable().getItems() )
        {
            if( item.getBounds().contains( x, y ) )
            {
                return item;
            }
        }
        
        return null;
    }
    
    private RuntimeValidationAssistant getRuntimeValidationAssistant()
    {
        return this.runtimeValidationAssistant;
    }
    
    private final class ContentProvider

        implements IStructuredContentProvider
    
    {
        public Object[] getElements( final Object element )
        {
            final IFacetedProjectWorkingCopy fpjwc = getFacetedProjectWorkingCopy();
            final ArrayList<IRuntime> runtimes = new ArrayList<IRuntime>();
            
            if( RuntimesPanel.this.showAllRuntimesSetting )
            {
                runtimes.addAll( RuntimeManager.getRuntimes() );
            }
            else
            {
                runtimes.addAll( fpjwc.getTargetableRuntimes() );
            }
            
            final IFacetedProject fpj = fpjwc.getFacetedProject();
            
            if( fpj != null )
            {
                for( IRuntime runtime : fpj.getTargetedRuntimes() )
                {
                    if( runtime instanceof UnknownRuntime )
                    {
                        runtimes.add( runtime );
                    }
                }
            }
            
            return runtimes.toArray();
        }
    
        public void dispose() { }
    
        public void inputChanged( final Viewer viewer,
                                  final Object oldObject,
                                  final Object newObject ) {}
    }
    
    private final class LabelProvider

        implements ILabelProvider, IColorProvider
    
    {
        private final ImageRegistry imageRegistry;
        
        public LabelProvider()
        {
            this.imageRegistry = new ImageRegistry();
        }
        
        public String getText( final Object element )
        {
            return ( (IRuntime) element ).getLocalizedName();
        }
        
        private String getImageRegistryKey( final IRuntime runtime,
                                            final boolean isPrimary,
                                            final IStatus validationResult )
        {
            final StringBuilder buf = new StringBuilder();
            
            buf.append( runtime.getName() );
            
            if( isPrimary )
            {
                buf.append( ",##primary##" ); //$NON-NLS-1$
            }
            
            if( validationResult != null && validationResult.getSeverity() == IStatus.ERROR )
            {
                buf.append( ",##error##" ); //$NON-NLS-1$
            }
            
            return buf.toString();
        }

        public Image getImage( final Object element )
        {
            final IRuntime r = (IRuntime) element;
            final IRuntime primary = getFacetedProjectWorkingCopy().getPrimaryRuntime();
            final boolean isPrimary = primary != null && primary.equals( r );
            final IStatus valResult = getRuntimeValidationAssistant().getValidationResult( r );
            final String imgid = getImageRegistryKey( r, isPrimary, valResult );
            
            Image image = this.imageRegistry.get( imgid );
            
            if( image == null )
            {
                final IDecorationsProvider decprov
                    = (IDecorationsProvider) r.getAdapter( IDecorationsProvider.class );

                final ImageDescriptor imgdesc
                    = new DecoratedRuntimeImageDescriptor( decprov.getIcon(), isPrimary, valResult );
                
                this.imageRegistry.put( imgid, imgdesc );
                image = this.imageRegistry.get( imgid );
            }

            if( RuntimesPanel.this.fpjwc.getTargetedRuntimes().contains( r ) )
            {
                RuntimesPanel.this.runtimes.setChecked( r, true );
            }
            else
            {
                RuntimesPanel.this.runtimes.setChecked( r, false );
            }
            
            if( ! getFacetedProjectWorkingCopy().getTargetableRuntimes().contains( r ) &&
                ! ( r instanceof UnknownRuntime ) )
            {
                final String greyedId = r.getName() + "##greyed##"; //$NON-NLS-1$
                Image greyed = this.imageRegistry.get( greyedId );
                
                if( greyed == null )
                {
                    greyed = new Image( null, image, SWT.IMAGE_GRAY );
                    this.imageRegistry.put( greyedId, greyed );
                }
                
                image = greyed;
            }
            
            return image;
        }
        
        public Color getForeground( final Object element )
        {
            if( ! getFacetedProjectWorkingCopy().getTargetableRuntimes().contains( element ) &&
                ! ( element instanceof UnknownRuntime ) )
            {
                return RuntimesPanel.this.colorGray;
            }
            else
            {
                return null;
            }
        }

        public Color getBackground( final Object element )
        {
            return null;
        }

        public void dispose()
        {
            this.imageRegistry.dispose();
        }

        public boolean isLabelProperty( final Object element, 
                                        final String property )
        {
            return false;
        }

        public void addListener( final ILabelProviderListener listener ) {}
        public void removeListener( final ILabelProviderListener listener ) {}
    }

    private final class Sorter

        extends ViewerSorter
    
    {
        public int compare( final Viewer viewer,
                            final Object a,
                            final Object b )
        {
            final IRuntime r1 = (IRuntime) a;
            final IRuntime r2 = (IRuntime) b;
            
            return r1.getLocalizedName().compareToIgnoreCase( r2.getLocalizedName() );
        }
    }
    
    private final class RuntimeComponentsContentProvider

        implements IStructuredContentProvider
    
    {
        public Object[] getElements( final Object element )
        {
            if( element == NO_RUNTIME_SELECTED_PLACEHOLDER )
            {
                return new Object[] { NO_RUNTIME_SELECTED_PLACEHOLDER };
            }
            else
            {
                final IRuntime r = (IRuntime) element;
                return r.getRuntimeComponents().toArray();
            }
        }
    
        public void dispose() { }
    
        public void inputChanged( final Viewer viewer,
                                  final Object oldObject,
                                  final Object newObject ) {}
    }
    
    private final class RuntimeComponentsLabelProvider

        implements ILabelProvider
    
    {
        private final ImageRegistry imageRegistry = new ImageRegistry();
        
        public String getText( final Object element )
        {
            if( element == NO_RUNTIME_SELECTED_PLACEHOLDER )
            {
                return Resources.noRuntimeSelectedLabel;
            }
            
            final IRuntimeComponent comp = (IRuntimeComponent) element;
            
            final IRuntimeComponentLabelProvider provider
                = (IRuntimeComponentLabelProvider) comp.getAdapter( IRuntimeComponentLabelProvider.class );
            
            if( provider == null )
            {
                final StringBuffer label = new StringBuffer();
                label.append( comp.getRuntimeComponentType().getId() );
                label.append( ' ' );
                label.append( comp.getRuntimeComponentVersion().getVersionString() );
                
                return label.toString();
            }
            else
            {
                return provider.getLabel();
            }
        }

        public Image getImage( final Object element )
        {
            if( element == NO_RUNTIME_SELECTED_PLACEHOLDER )
            {
                return null;
            }

            final IRuntimeComponent rc = (IRuntimeComponent) element;
            final IRuntimeComponentType rct = rc.getRuntimeComponentType();
            final IRuntimeComponentVersion rcv = rc.getRuntimeComponentVersion();
            
            final String key = rct.getId() + ":" + rcv.getVersionString(); //$NON-NLS-1$
            Image image = this.imageRegistry.get( key );
            
            if( image == null )
            {
                final IDecorationsProvider decprov
                    = (IDecorationsProvider) rcv.getAdapter( IDecorationsProvider.class );
                
                this.imageRegistry.put( key, decprov.getIcon() );
                image = this.imageRegistry.get( key );
            }

            return image;
        }
        
        public void dispose()
        {
            this.imageRegistry.dispose();
        }

        public boolean isLabelProperty( final Object element, 
                                        final String property )
        {
            return false;
        }

        public void addListener( final ILabelProviderListener listener ) {}
        public void removeListener( final ILabelProviderListener listener ) {}
    }
    
    private static final class DecoratedRuntimeImageDescriptor 
    
        extends CompositeImageDescriptor 
        
    {
        private static final String PRIMARY_RUNTIME_OVERLAY_IMG_LOCATION
            = "images/primary-runtime-overlay.gif"; //$NON-NLS-1$
        
        private static final ImageData PRIMARY_RUNTIME_OVERLAY
            = FacetUiPlugin.getImageDescriptor( PRIMARY_RUNTIME_OVERLAY_IMG_LOCATION ).getImageData();
        
        private static final String ERROR_OVERLAY_IMG_LOCATION
            = "images/error-overlay.gif"; //$NON-NLS-1$
        
        private static final ImageData ERROR_OVERLAY
            = FacetUiPlugin.getImageDescriptor( ERROR_OVERLAY_IMG_LOCATION ).getImageData();

        private static final String WARNING_OVERLAY_IMG_LOCATION
            = "images/warning-overlay.gif"; //$NON-NLS-1$
        
        private static final ImageData WARNING_OVERLAY
            = FacetUiPlugin.getImageDescriptor( WARNING_OVERLAY_IMG_LOCATION ).getImageData();
    
        private final ImageData base;
        private final Point size;
        private boolean isPrimary;
        private IStatus valResult;
        
        public DecoratedRuntimeImageDescriptor( final ImageDescriptor base,
                                                final boolean isPrimary,
                                                final IStatus valResult ) 
        {
            this.base = base.getImageData();
            this.size = new Point( this.base.width, this.base.height );
            this.isPrimary = isPrimary;
            this.valResult = valResult;
        }
    
        protected void drawCompositeImage( final int width, 
                                           final int height ) 
        {
            drawImage( this.base, 0, 0 );
            
            if( this.isPrimary )
            {
                drawImage( PRIMARY_RUNTIME_OVERLAY, width - PRIMARY_RUNTIME_OVERLAY.width, 
                           height - PRIMARY_RUNTIME_OVERLAY.height );
            }
            
            if( this.valResult != null && ! this.valResult.isOK() )
            {
                final ImageData valOverlay
                    = this.valResult.getSeverity() == IStatus.ERROR 
                      ? ERROR_OVERLAY : WARNING_OVERLAY;
                
                drawImage( valOverlay, 0, height - valOverlay.height );
            }
        }
    
        protected Point getSize()
        {
            return this.size;
        }
    }
    
    private final class ValidationProblemToolTip
    
        extends BasicToolTip
        
    {
        public ValidationProblemToolTip( final Control control )
        {
            super( control );
        }
        
        @Override
        protected Composite createToolTipContentArea( final Event event,
                                                      final Composite parent )
        {
            final IStatus validationResult = getValidationResult( event );
            setMessage( validationResult.getMessage() );
            return super.createToolTipContentArea( event, parent );
        }
        
        @Override
        protected boolean shouldCreateToolTip( final Event event ) 
        {
            return ! getValidationResult( event ).isOK();
        }
        
        private IRuntime getRuntime( final Event event )
        {
            final TableItem item = getTableItem( event.x, event.y );
            return item != null ? (IRuntime) item.getData() : null;
        }
        
        private IStatus getValidationResult( final Event event )
        {
            final IRuntime runtime = getRuntime( event );
            IStatus result = null;
            
            if( runtime != null )
            {
                result = RuntimesPanel.this.runtimeValidationAssistant.getValidationResult( runtime );
            }
            
            if( result == null )
            {
                result = Status.OK_STATUS;
            }
            
            return result;
        }
    }
    
    private final class RuntimeValidationAssistant
    {
        private final Map<String,IStatus> validationResults;
        private final IRuntimeLifecycleListener runtimeLifecycleListener;
        
        public RuntimeValidationAssistant()
        {
            this.validationResults = new HashMap<String,IStatus>();
            
            this.runtimeLifecycleListener = new IRuntimeLifecycleListener()
            {
                public void handleEvent( final IRuntimeLifecycleEvent event )
                {
                    final IValidationStatusChangedEvent evt = (IValidationStatusChangedEvent) event;
                    setValidationResult( evt.getRuntime(), evt.getNewValidationStatus() );
                    handleRuntimeValidationResultChanged();
                }
            };
            
            final Thread initialValidationThread = new Thread()
            {
                public void run()
                {
                    for( IRuntime runtime : RuntimeManager.getRuntimes() )
                    {
                        final IStatus result = runtime.validate( new NullProgressMonitor() );
                        
                        synchronized( RuntimeValidationAssistant.this.validationResults )
                        {
                            if( getValidationResult( runtime ) == null )
                            {
                                setValidationResult( runtime, result );
                            }
                        }
                    }
                    
                    RuntimeManager.addListener( RuntimeValidationAssistant.this.runtimeLifecycleListener, 
                                                IRuntimeLifecycleEvent.Type.VALIDATION_STATUS_CHANGED );
                    
                    handleRuntimeValidationResultChanged();
                }
            };
            
            initialValidationThread.start();
        }
        
        public IStatus getValidationResult( final IRuntime runtime )
        {
            synchronized( this.validationResults )
            {
                return this.validationResults.get( runtime.getName() );
            }
        }
        
        private void setValidationResult( final IRuntime runtime,
                                          final IStatus validationResult )
        {
            synchronized( this.validationResults )
            {
                this.validationResults.put( runtime.getName(), validationResult );
            }
        }
        
        public void dispose()
        {
            RuntimeManager.removeListener( this.runtimeLifecycleListener );
        }
    }

    private static final class Resources
    
        extends NLS
        
    {
        public static String runtimeCompositionLabel;
        public static String makePrimaryLabel;
        public static String newRuntimeButtonLabel;
        public static String showAllRuntimes;
        public static String noRuntimeSelectedLabel;
        
        static
        {
            initializeMessages( RuntimesPanel.class.getName(), 
                                Resources.class );
        }
    }
    
}
