/******************************************************************************
 * 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
 ******************************************************************************/

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.draw2d.AbsoluteBendpoint;
import org.eclipse.draw2d.AbstractBorder;
import org.eclipse.draw2d.AbstractLayout;
import org.eclipse.draw2d.ChopboxAnchor;
import org.eclipse.draw2d.CompoundBorder;
import org.eclipse.draw2d.Ellipse;
import org.eclipse.draw2d.EllipseAnchor;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.StackLayout;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.graph.DirectedGraph;
import org.eclipse.draw2d.graph.DirectedGraphLayout;
import org.eclipse.draw2d.graph.Edge;
import org.eclipse.draw2d.graph.Node;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.wst.common.project.facet.core.IConstraint;
import org.eclipse.wst.common.project.facet.core.IGroup;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IVersionExpr;

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

public final class ConstraintDisplayDialog

    extends Dialog
    
{
    private static final Font BOLD_FONT;
    
    static
    {
        final FontData sys 
            = Display.getCurrent().getSystemFont().getFontData()[ 0 ];
        
        final FontData bold
            = new FontData( sys.getName(), sys.getHeight(), SWT.BOLD );
        
        BOLD_FONT = new Font( Display.getCurrent(), bold );
    }
    
    private final IConstraint constraint;
    private final Point location;
    private int width;
    private int height;
    
    protected ConstraintDisplayDialog( final Shell parentShell,
                                       final Point location,
                                       final IConstraint constraint )
    {
        super( parentShell );
        
        setShellStyle( SWT.APPLICATION_MODAL | getDefaultOrientation() );
        
        this.constraint = constraint;
        this.location = location;
    }

    protected Control createDialogArea( final Composite parent ) 
    {
        final Canvas canvas = new Canvas( parent, SWT.NONE );
        canvas.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
        
        final Color infoBackgroundColor
            = parent.getDisplay().getSystemColor( SWT.COLOR_INFO_BACKGROUND );
        
        canvas.setBackground( infoBackgroundColor );
        
        final LightweightSystem lws = new LightweightSystem( canvas );
        final Figure outer = new Figure();
        outer.setLayoutManager( new ToolbarLayout() );
        lws.setContents( outer );
        final Figure contents = new Figure();
        contents.setBorder( new MarginBorder( 10 ) );
        outer.add( contents );
        
        createConstraintGraph( contents, null, this.constraint );
        contents.setLayoutManager( new GraphLayoutManager() );
        
        final Label escLabel = new Label( Resources.pressEscToClose );
        escLabel.setLabelAlignment( Label.RIGHT );
        escLabel.setBorder( new CompoundBorder( new DividerBorder( 2 ), new MarginBorder( 2 ) ) );
        
        outer.add( escLabel );

        final Dimension size = outer.getPreferredSize();
        this.width = ( size.width < 200 ? 200 : size.width );
        this.height = size.height;
        
        return canvas;
    }
    
    protected Control createButtonBar( final Composite parent )
    {
        return null;
    }
    
    protected Point getInitialLocation( final Point size )
    {
        return this.location;
    }
    
    protected Point getInitialSize()
    {
        return new Point( this.width, this.height );
    }
    
    private void createConstraintGraph( final IFigure container,
                                        final PolylineConnection parentCon,
                                        final IConstraint constraint )
    {
        if( constraint.getType() == IConstraint.Type.AND ||
            constraint.getType() == IConstraint.Type.OR )
        {
            if( constraint.getOperands().size() == 1 )
            {
                final IConstraint child
                    = (IConstraint) constraint.getOperand( 0 );
                
                createConstraintGraph( container, parentCon, child ); 
            }
            else
            {
                final AndOrConstraintFigure node 
                    = new AndOrConstraintFigure( constraint );
                
                container.add( node );
                
                if( parentCon != null )
                {
                    parentCon.setTargetAnchor( new EllipseAnchor( node ) );
                }
                
                for( Object operand : constraint.getOperands() )
                {
                    final IConstraint child = (IConstraint) operand;
                    final PolylineConnection childEdge = new PolylineConnection();
                    container.add( childEdge );
                    childEdge.setSourceAnchor( new EllipseAnchor( node ) );
                    createConstraintGraph( container, childEdge, child );
                }
            }
        }
        else if( constraint.getType() == IConstraint.Type.REQUIRES )
        {
            final RequiresConstraintFigure node 
                = new RequiresConstraintFigure( constraint );
            
            container.add( node );

            if( parentCon != null )
            {
                parentCon.setTargetAnchor( new ChopboxAnchor( node ) );
            }
        }
        else if( constraint.getType() == IConstraint.Type.CONFLICTS )
        {
            final ConflictsConstraintFigure node 
                = new ConflictsConstraintFigure( constraint );
        
            container.add( node );

            if( parentCon != null )
            {
                parentCon.setTargetAnchor( new ChopboxAnchor( node ) );
            }
        }
        else
        {
            throw new IllegalStateException();
        }
    }
    
    private static final class GraphLayoutManager
    
        extends AbstractLayout
        
    {
        private int laidout = 0;
        
        protected Dimension calculatePreferredSize( final IFigure container, 
                                                    final int wHint, 
                                                    final int hHint )
        {
            container.validate();
            List children = container.getChildren();
            Rectangle result = new Rectangle().setLocation(container.getClientArea().getLocation());
            for (int i = 0; i < children.size(); i++)
                result.union(((IFigure) children.get(i)).getBounds());
            result.resize(container.getInsets().getWidth() + 2, container.getInsets().getHeight() + 2);
            return result.getSize();        
        }

        @SuppressWarnings( "unchecked" )
        public void layout( final IFigure container )
        {
            if( this.laidout > 5 )
            {
                return;
            }
            
            // Create the graph.
            
            final DirectedGraph graph = new DirectedGraph();
            final Map<IFigure,Node> nodes = new HashMap<IFigure,Node>();
            
            for( Object child : container.getChildren() )
            {
                final IFigure childFigure = (IFigure) child;
                
                if( ! ( childFigure instanceof PolylineConnection ) )
                {
                    final Node node = new Node( childFigure );
                    final Dimension size = childFigure.getPreferredSize();
                    node.height = size.height;
                    node.width = size.width;
                    graph.nodes.add( node );
                    nodes.put( childFigure, node );
                }
            }
            
            for( Object child : container.getChildren() )
            {
                if( child instanceof PolylineConnection )
                {
                    final PolylineConnection cn = (PolylineConnection) child;
                    
                    final IFigure source = cn.getSourceAnchor().getOwner();
                    final Node sourceNode = nodes.get( source );
                    
                    final IFigure target = cn.getTargetAnchor().getOwner();
                    final Node targetNode = nodes.get( target );
                    
                    final Edge edge = new Edge( cn, sourceNode, targetNode );
                    graph.edges.add( edge );
                }
            }
            
            // Call the graph layout algorith to determine node positions.
            
            ( new DirectedGraphLayout() ).visit( graph );
            
            // Layout nodes based on the results of the graph layout.

            for( Object obj : graph.nodes )
            {
                final Node node = (Node) obj;
                final IFigure figure = (IFigure) node.data;
                
                final Rectangle bounds 
                    = new Rectangle( node.x + 10, node.y - 6, 
                                     figure.getPreferredSize().width,
                                     figure.getPreferredSize().height );
                
                figure.setBounds( bounds );
            }

            for( Object obj : graph.edges )
            {
                final Edge edge = (Edge) obj;
                final PolylineConnection cn = (PolylineConnection) edge.data;
                
                if( edge.vNodes == null )
                {
                    cn.setRoutingConstraint( Collections.EMPTY_LIST );
                }
                else
                {
                    final List<AbsoluteBendpoint> bends = new ArrayList<AbsoluteBendpoint>();
                    
                    for( Object obj2 : edge.vNodes )
                    {
                        final Node vn = (Node) obj2;
                        
                        if( edge.isFeedback() )
                        {
                            bends.add( new AbsoluteBendpoint( vn.x, vn.y + vn.height ) );
                            bends.add( new AbsoluteBendpoint( vn.x, vn.y ) );
                        }
                        else
                        {
                            bends.add( new AbsoluteBendpoint( vn.x, vn.y ) );
                            bends.add( new AbsoluteBendpoint( vn.x, vn.y + vn.height ) );
                        }
                    }
                    
                    cn.setRoutingConstraint( bends );
                }
            }
            
            this.laidout++;
        }
    }
    
    private static final class DividerBorder
        
        extends AbstractBorder 
        
    {
        private final int lines;
        private final Insets insets;
        
        public DividerBorder( final int lines )
        {
            this.lines = lines;
            this.insets = new Insets( 1 + ( this.lines - 1 ) * 2 );
        }
        
        public Insets getInsets( final IFigure figure ) 
        {
            return this.insets;
        }
        
        public void paint( final IFigure figure, 
                           final Graphics graphics, 
                           final Insets insets ) 
        {
            final Rectangle paintRectangle 
                = getPaintRectangle( figure, insets );
            
            final int xLeft = paintRectangle.getTopLeft().x;
            final int xRight = paintRectangle.getTopRight().x;
            
            int y = paintRectangle.getTopLeft().y;
            
            for( int i = 0; i < this.lines; i++, y += 2 )
            {
                graphics.drawLine( xLeft, y, xRight, y );
            }
        }
    }
    
    private static final class DashedLineBorder
    
        extends LineBorder
        
    {
        public DashedLineBorder()
        {
            super( 1 );
        }
        
        public void paint(IFigure figure, Graphics graphics, Insets insets) 
        {
            graphics.setLineStyle( SWT.LINE_DASH );
            super.paint( figure, graphics, insets );
            graphics.setLineStyle( SWT.LINE_SOLID );
        }
    }
    
    private static final class AndOrConstraintFigure
    
        extends Figure
        
    {
        public AndOrConstraintFigure( final IConstraint constraint )
        {
            setLayoutManager( new StackLayout() );
            
            final String labelText;
            final Color background;
            
            if( constraint.getType() == IConstraint.Type.AND )
            {
                labelText = Resources.andOperator;
                background = new Color( null, 0, 175, 0 );
            }
            else if( constraint.getType() == IConstraint.Type.OR )
            {
                labelText = Resources.orOperator;
                background = new Color( null, 255, 128, 0 ); 
            }
            else
            {
                throw new IllegalStateException();
            }
            
            final Ellipse circle = new Ellipse();
            circle.setOpaque( true );
            circle.setBackgroundColor( background );
            add( circle );
            
            final Label label = new Label();
            label.setFont( BOLD_FONT );
            label.setText( labelText );
            add( label );
        }
        
        public Dimension getPreferredSize( final int wHint, 
                                           final int hHint )
        {
            return new Dimension( 35, 35 );
        }
    }
    
    private static final class RequiresConstraintFigure
    
        extends Figure
        
    {
        public RequiresConstraintFigure( final IConstraint constraint )
        {
            final Boolean soft 
                = (Boolean) constraint.getOperand( constraint.getOperands().size() - 1 );
            
            setLayoutManager( new ToolbarLayout() );
            setBackgroundColor( new Color( null, 255, 255, 255 ) );
            setOpaque( true );
            
            setBorder( soft.booleanValue() 
                       ? new DashedLineBorder() : new LineBorder( 1 )  );
            
            final Label headerLabel = new Label();
            headerLabel.setFont( BOLD_FONT );
            headerLabel.setBorder( new MarginBorder( 2 ) );
            add( headerLabel );
            
            final StringBuffer bodyLabelText = new StringBuffer();
            final Object firstOperand = constraint.getOperand( 0 );
            
            if( firstOperand instanceof IGroup )
            {
                final IGroup group = (IGroup) firstOperand;
                
                headerLabel.setText( Resources.requiresGroupMemberOperator );
                bodyLabelText.append( group.toString() );
            }
            else
            {
                final IProjectFacet f = (IProjectFacet) firstOperand;
                final IVersionExpr vexpr = (IVersionExpr) constraint.getOperand( 1 );
    
                headerLabel.setText( Resources.requiresFacetOperator );
                
                bodyLabelText.append( f.getLabel() );
                
                if( ! vexpr.toString().equals( IVersionExpr.WILDCARD_SYMBOL ) )
                {
                    bodyLabelText.append( ' ' );
                    bodyLabelText.append( vexpr.toDisplayString() );
                }
            }
            
            final Label bodyLabel = new Label();
            bodyLabel.setText( bodyLabelText.toString() );
            bodyLabel.setBorder( new CompoundBorder( new DividerBorder( 1 ), new MarginBorder( 2 ) ) );
            add( bodyLabel );
        }
    }

    private static final class ConflictsConstraintFigure
    
        extends Figure
        
    {
        public ConflictsConstraintFigure( final IConstraint constraint )
        {
            setLayoutManager( new ToolbarLayout() );
            setBorder( new LineBorder( 1 ) );
            setOpaque( true );
            setBackgroundColor( new Color( null, 255, 255, 255 ) );
            
            final Label headerLabel = new Label();
            headerLabel.setFont( BOLD_FONT );
            headerLabel.setBorder( new MarginBorder( 2 ) );
            add( headerLabel );
            
            final StringBuffer bodyLabelText = new StringBuffer();
            final Object firstOperand = constraint.getOperand( 0 );
            
            if( firstOperand instanceof IGroup )
            {
                headerLabel.setText( Resources.conflictsWithGroupOperator );
                
                bodyLabelText.append( ( (IGroup) firstOperand ).getId() );
            }
            else
            {
                headerLabel.setText( Resources.conflictsWithFacetOperator );
                
                final IProjectFacet f = (IProjectFacet) firstOperand;
                
                bodyLabelText.append( f.getLabel() );
                
                if( constraint.getOperands().size() == 2 )
                {
                    final IVersionExpr vexpr 
                        = (IVersionExpr) constraint.getOperand( 1 );
                    
                    bodyLabelText.append( ' ' );
                    bodyLabelText.append( vexpr.toDisplayString() );
                }
            }

            final Label bodyLabel = new Label();
            bodyLabel.setText( bodyLabelText.toString() );
            bodyLabel.setBorder( new CompoundBorder( new DividerBorder( 1 ), new MarginBorder( 2 ) ) );
            add( bodyLabel );
        }
    }

    private static final class Resources
    
        extends NLS
        
    {
        public static String pressEscToClose;
        public static String andOperator;
        public static String orOperator;
        public static String requiresFacetOperator;
        public static String requiresGroupMemberOperator;
        public static String conflictsWithGroupOperator;
        public static String conflictsWithFacetOperator;
        
        static
        {
            initializeMessages( ConstraintDisplayDialog.class.getName(), 
                                Resources.class );
        }
    }
    
}
