/******************************************************************************
 * Copyright (c) 2010 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.gl;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.glmargins;

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.layout.GridDataFactory;
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 ) );
        
        this.makePrimaryButton = new Button( buttons, SWT.PUSH );
        this.makePrimaryButton.setText( Resources.makePrimaryLabel );
        this.makePrimaryButton.setEnabled( false );
        GridDataFactory.defaultsFor( this.makePrimaryButton ).applyTo( this.makePrimaryButton );
        
        this.makePrimaryButton.addSelectionListener
        (
            new SelectionAdapter()
            {
                public void widgetSelected( final SelectionEvent e )
                {
                    handleMakePrimarySelected();
                }
            }
        );
        
        this.newRuntimeButton = new Button( buttons, SWT.PUSH );
        this.newRuntimeButton.setText( Resources.newRuntimeButtonLabel );
        GridDataFactory.defaultsFor( this.newRuntimeButton ).applyTo( this.newRuntimeButton );

        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 );
        }
    }
    
}
