/******************************************************************************
 * Copyright (c) 2005-2007 BEA Systems, Inc.
 * 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
 *    David Schneider, david.schneider@unisys.com - [142500] WTP properties pages fonts don't follow Eclipse preferences
 ******************************************************************************/

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.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.Platform;
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.Label;
import org.eclipse.swt.widgets.Shell;
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.ui.IDecorationsProvider;
import org.eclipse.wst.common.project.facet.ui.IRuntimeComponentLabelProvider;
import org.eclipse.wst.common.project.facet.ui.internal.AbstractDataModel.IDataModelListener;
import org.osgi.framework.Bundle;

/**
 * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
 */

public final class RuntimesPanel

    extends Composite

{
    private static final Object NO_RUNTIME_SELECTED_PLACEHOLDER = new Object();
    
    private final ChangeTargetedRuntimesDataModel model;
    private boolean showAllRuntimesSetting;
    private final Label runtimesLabel;
    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<IDataModelListener> listeners;
    private Color colorGray;
    
    public RuntimesPanel( final Composite parent,
                          final int style,
                          final ChangeTargetedRuntimesDataModel model )
    {
        super( parent, style );
        
        this.listeners = new ArrayList<IDataModelListener>();
        
        addDisposeListener
        ( 
            new DisposeListener()
            {
                public void widgetDisposed( final DisposeEvent e )
                {
                    handleWidgetDisposed();
                }
            }
        );
        
        // Bind to the data model.
        
        this.model = model;
        
        addDataModelListener
        ( 
            ChangeTargetedRuntimesDataModel.EVENT_AVAILABLE_RUNTIMES_CHANGED, 
            new IDataModelListener()
            {
                public void handleEvent()
                {
                    handleAvailableRuntimesChanged();
                }
            }
        );
        
        addDataModelListener
        ( 
            ChangeTargetedRuntimesDataModel.EVENT_TARGETABLE_RUNTIMES_CHANGED, 
            new IDataModelListener()
            {
                public void handleEvent()
                {
                    handleTargetableRuntimesChanged();
                }
            }
        );
        
        addDataModelListener
        ( 
            ChangeTargetedRuntimesDataModel.EVENT_TARGETED_RUNTIMES_CHANGED, 
            new IDataModelListener()
            {
                public void handleEvent()
                {
                    handleTargetedRuntimesChanged();
                }
            }
        );
        
        addDataModelListener
        ( 
            ChangeTargetedRuntimesDataModel.EVENT_PRIMARY_RUNTIME_CHANGED, 
            new IDataModelListener()
            {
                public void handleEvent()
                {
                    handlePrimaryRuntimeChanged();
                }
            }
        );
        
        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 = 0;
        layout.marginWidth = 0;

        setLayout( layout );

        this.runtimesLabel = new Label( this, SWT.NONE );
        this.runtimesLabel.setText( Resources.runtimesLabel );
        this.runtimesLabel.setLayoutData( gdhfill() );
        
        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() );
        
        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 );
        
        this.runtimeComponents = new TableViewer( this, SWT.BORDER );
        this.runtimeComponents.getTable().setLayoutData( gdhhint( gdhfill(), 50 ) );
        this.runtimeComponents.getTable().setBackground( infoBackgroundColor );
        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.model.getPrimaryRuntime();
        
	    Dialog.applyDialogFont( parent );
    }
    
    public ChangeTargetedRuntimesDataModel getDataModel()
    {
        return this.model;
    }
    
    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.model.getTargetedRuntimes();
        
        for( IRuntime r : this.model.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.model.getPrimaryRuntime();
        
        if( this.currentPrimaryRuntime != null )
        {
            this.runtimes.update( this.currentPrimaryRuntime, null );
        }
    }
    
    private void handleCheckStateChanged( final CheckStateChangedEvent e )
    {
        final IRuntime runtime = (IRuntime) e.getElement();
        
        if( ! this.model.getTargetableRuntimes().contains( runtime ) &&
            e.getChecked() )
        {
            this.runtimes.setChecked( runtime, false );
            return;
        }
        
        if( e.getChecked() )
        {
            this.model.addTargetedRuntime( runtime );
        }
        else
        {
            this.model.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.model.getPrimaryRuntime() != null && 
                ! this.model.getPrimaryRuntime().equals( r ) &&
                this.model.getTargetableRuntimes().contains( r ) )
            {
                this.makePrimaryButton.setEnabled( true );
            }
            else
            {
                this.makePrimaryButton.setEnabled( false );
            }
        }
    }
    
    private void handleShowAllRuntimesSelected()
    {
        this.showAllRuntimesSetting 
            = this.showAllRuntimesCheckbox.getSelection();
        
        refresh();
    }
    
    private void handleMakePrimarySelected()
    {
        this.model.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 ) )
            {
                this.model.refreshTargetableRuntimes();
            }
        }
        catch( Exception e )
        {
            FacetUiPlugin.log( e );
        }
    }

    private void handleWidgetDisposed()
    {
        removeDataModelListeners();
        
        this.colorGray.dispose();
    }
    
    private void refresh()
    {
        this.runtimes.refresh();

        final Set<IRuntime> untargetable = new HashSet<IRuntime>( this.model.getAllRuntimes() );
        untargetable.removeAll( this.model.getTargetableRuntimes() );
        
        this.runtimes.setCheckedElements( this.model.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 String event,
                                       final IDataModelListener listener )
    {
        this.model.addListener( event, listener );
        this.listeners.add( listener );
    }
    
    private void removeDataModelListeners()
    {
        for( IDataModelListener listener : this.listeners )
        {
            this.model.removeListener( listener );
        }
    }
    
    private final class ContentProvider

        implements IStructuredContentProvider
    
    {
        public Object[] getElements( final Object element )
        {
            if( RuntimesPanel.this.showAllRuntimesSetting )
            {
                return getDataModel().getAllRuntimes().toArray();
            }
            else
            {
                return getDataModel().getTargetableRuntimes().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();
        }

        public Image getImage( final Object element )
        {
            final IRuntime r = (IRuntime) element;
            
            final IRuntimeComponent rc = r.getRuntimeComponents().get( 0 );
            final IRuntimeComponentType rct = rc.getRuntimeComponentType();
            
            final IRuntime primary = getDataModel().getPrimaryRuntime();
            final boolean isPrimary = primary != null && primary.equals( r );
            
            final String imgid
                = ( isPrimary ? "p:" : "s" ) //$NON-NLS-1$ //$NON-NLS-2$
                  + rct.getId();
            
            Image image = this.imageRegistry.get( imgid );
            
            if( image == null )
            {
                final IDecorationsProvider decprov
                    = (IDecorationsProvider) rct.getAdapter( IDecorationsProvider.class );
                
                ImageDescriptor imgdesc = decprov.getIcon();
                
                if( isPrimary )
                {
                    imgdesc = new PrimaryRuntimeImageDescriptor( imgdesc );
                }
                
                this.imageRegistry.put( imgid, imgdesc );
                image = this.imageRegistry.get( imgid );
            }

            if( getDataModel().getTargetableRuntimes().contains( r ) )
            {
                if( RuntimesPanel.this.model.getTargetedRuntimes().contains( r ) )
                {
                    RuntimesPanel.this.runtimes.setChecked( r, true );
                }
                else
                {
                    RuntimesPanel.this.runtimes.setChecked( r, false );
                }
                
                return image;
            }
            else
            {
                RuntimesPanel.this.runtimes.setChecked( r, false );
                
                final String greyedId = rct.getId() + "##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 );
                }
                
                return greyed;
            }
        }
        
        public Color getForeground( final Object element )
        {
            if( ! getDataModel().getTargetableRuntimes().contains( element ) )
            {
                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();
            
            Image image = this.imageRegistry.get( rct.getId() );
            
            if( image == null )
            {
                final IDecorationsProvider decprov
                    = (IDecorationsProvider) rct.getAdapter( IDecorationsProvider.class );
                
                this.imageRegistry.put( rct.getId(), decprov.getIcon() );
                image = this.imageRegistry.get( rct.getId() );
            }

            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 PrimaryRuntimeImageDescriptor 
    
        extends CompositeImageDescriptor 
        
    {
        private static final String OVERLAY_IMG_LOCATION
            = "images/primary-runtime-overlay.gif"; //$NON-NLS-1$
        
        private static final ImageData OVERLAY
            = FacetUiPlugin.getImageDescriptor( OVERLAY_IMG_LOCATION ).getImageData();
        
        private final ImageData base;
        private final Point size;
        
        public PrimaryRuntimeImageDescriptor( 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 Resources
    
        extends NLS
        
    {
        public static String runtimesLabel;
        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 );
        }
    }
    
}
