package view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

import graph.LayeredGraphNode;
import graph.RandomGraphGenerator;
import lib.SimpleNodePlacement;
import lib.SweepCrossingMinimizer;

public class RandomGraphDialog extends JDialog {
    
    private static final long serialVersionUID = 1L;
    
    private JTextField pSubgraph;
    private JTextField pEdge;
    private JTextField minLayers;
    private JTextField maxLayers;
    private JTextField minNodes;
    private JTextField maxNodes;
    private JTextField maxDepth;
    
    public RandomGraphDialog()
    {
        setTitle( "Generate random graph" );
        setLayout( new GridBagLayout() );
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        add( new JLabel( "P(subgraph exists)"), c );
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 0;
        pSubgraph = new JTextField( "0.1" );
        pSubgraph.setPreferredSize( new Dimension( 100, 20 ) );
        pSubgraph.addFocusListener( new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                pSubgraph.setBackground( Color.WHITE );
            }

            @Override
            public void focusLost(FocusEvent e) {
                try {
                    double d = Double.parseDouble( pSubgraph.getText() );
                    if( d > 1 || d < 0 )
                        pSubgraph.setBackground( Color.RED );
                } catch( Exception e1 )
                {
                    pSubgraph.setBackground( Color.RED );
                }
            }
        });
        add( pSubgraph, c );
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 1;
        add( new JLabel( "P(edge exists)"), c );
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 1;
        pEdge = new JTextField( "0.3" );
        pEdge.setPreferredSize( new Dimension( 100, 20 ) );
        pEdge.addFocusListener( new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                pEdge.setBackground( Color.WHITE );
            }

            @Override
            public void focusLost(FocusEvent e) {
                try {
                    double d = Double.parseDouble( pEdge.getText() );
                    if( d > 1 || d < 0 )
                        pEdge.setBackground( Color.RED );
                } catch( Exception e1 )
                {
                    pEdge.setBackground( Color.RED );
                }
            }
        });
        add( pEdge, c );
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 2;
        add( new JLabel( "min. num. layers"), c );
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 2;
        minLayers = new JTextField( "5" );
        maxLayers = new JTextField( "5" );
        minLayers.setPreferredSize( new Dimension( 100, 20 ) );
        minLayers.addFocusListener( new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                minLayers.setBackground( Color.WHITE );
            }

            @Override
            public void focusLost(FocusEvent e) {
                try {
                    int i = Integer.parseInt( minLayers.getText() );
                    int max = Integer.parseInt( maxLayers.getText() );
                    if( i < 1 || i > max )
                        minLayers.setBackground( Color.RED );
                    else
                        maxLayers.setBackground( Color.WHITE );
                } catch( Exception e1 )
                {
                    minLayers.setBackground( Color.RED );
                }
            }
        });
        add( minLayers, c );
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 3;
        add( new JLabel( "max. num. layers"), c );
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 3;
        maxLayers.setPreferredSize( new Dimension( 100, 20 ) );
        maxLayers.addFocusListener( new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                maxLayers.setBackground( Color.WHITE );
            }

            @Override
            public void focusLost(FocusEvent e) {
                try {
                    int i = Integer.parseInt( maxLayers.getText() );
                    int min = Integer.parseInt( minLayers.getText() );
                    if( i < min )
                        maxLayers.setBackground( Color.RED );
                    else if( min > 0 )
                        minLayers.setBackground( Color.WHITE );
                } catch( Exception e1 )
                {
                    maxLayers.setBackground( Color.RED );
                }
            }
        });
        add( maxLayers, c );
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 4;
        add( new JLabel( "min. num. nodes"), c );
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 4;
        minNodes = new JTextField( "5" );
        maxNodes = new JTextField( "5" );
        minNodes.setPreferredSize( new Dimension( 100, 20 ) );
        minNodes.setToolTipText( "between 1 and 'min. num. nodes'" );
        minNodes.addFocusListener( new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                minNodes.setBackground( Color.WHITE );
            }

            @Override
            public void focusLost(FocusEvent e) {
                try {
                    int i = Integer.parseInt( minNodes.getText() );
                    int max = Integer.parseInt( maxNodes.getText() );
                    if( i < 1 || i > max )
                        minNodes.setBackground( Color.RED );
                    else
                        minNodes.setBackground( Color.WHITE );
                } catch( Exception e1 )
                {
                    minNodes.setBackground( Color.RED );
                }
            }
        });
        add( minNodes, c );
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 5;
        add( new JLabel( "max. num. nodes"), c );
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 5;
        maxNodes.setPreferredSize( new Dimension( 100, 20 ) );
        maxNodes.setToolTipText( "between 'min. num. nodes' and +Inf" );
        maxNodes.addFocusListener( new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                maxNodes.setBackground( Color.WHITE );
            }

            @Override
            public void focusLost(FocusEvent e) {
                try {
                    int i = Integer.parseInt( maxNodes.getText() );
                    int min = Integer.parseInt( minNodes.getText() );
                    if( i < min )
                        maxNodes.setBackground( Color.RED );
                    else if( min > 0 )
                        minNodes.setBackground( Color.WHITE );
                } catch( Exception e1 )
                {
                    maxNodes.setBackground( Color.RED );
                }
            }
        });
        add( maxNodes, c );
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 6;
        add( new JLabel( "max. hier. depth"), c );
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 6;
        maxDepth = new JTextField( "1" );
        maxDepth.setPreferredSize( new Dimension( 100, 20 ) );
        maxDepth.setToolTipText( "between 1 and +Inf" );
        maxDepth.addFocusListener( new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                maxDepth.setBackground( Color.WHITE );
            }

            @Override
            public void focusLost(FocusEvent e) {
                try {
                    int i = Integer.parseInt( maxDepth.getText() );
                    if( i < 1 )
                        maxDepth.setBackground( Color.RED );
                } catch( Exception e1 )
                {
                    maxDepth.setBackground( Color.RED );
                }
            }
        });
        add( maxDepth, c );
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 7;
        c.gridwidth = 2;
        JButton gen = new JButton( "generate");
        gen.addActionListener( new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                double pSubGraphD = Double.parseDouble( pSubgraph.getText() );
                double pEdgeD = Double.parseDouble( pEdge.getText() );
                int minLayerI = Integer.parseInt( minLayers.getText() );
                int maxLayerI = Integer.parseInt( maxLayers.getText() );
                int minNodeI = Integer.parseInt( minNodes.getText() );
                int maxNodeI = Integer.parseInt( maxNodes.getText() );
                int maxDepthI = Integer.parseInt( maxDepth.getText() );
                boolean ok = true;
                if( pSubGraphD < 0 || pSubGraphD > 1 )
                {
                    pSubgraph.setBackground( Color.RED );
                    ok = false;
                }
                if( pEdgeD < 0 || pEdgeD > 1 )
                {
                    pEdge.setBackground( Color.RED );
                    ok = false;
                }
                if( minLayerI < 1 )
                {
                    minLayers.setBackground( Color.RED );
                    ok = false;
                }
                if( maxLayerI < minLayerI )
                {
                    maxLayers.setBackground( Color.RED );
                    ok = false;
                }
                if( minNodeI < 1 )
                {
                    minNodes.setBackground( Color.RED );
                    ok = false;
                }
                if( maxNodeI < minNodeI )
                {
                    maxNodes.setBackground( Color.RED );
                    ok = false;
                }
                if( maxDepthI < 1 )
                {
                    maxDepth.setBackground( Color.RED );
                    ok = false;
                }
                if( ok )
                {                            
                    RandomGraphGenerator r = new RandomGraphGenerator( pSubGraphD, pEdgeD, minLayerI, maxLayerI, minNodeI, maxNodeI, maxDepthI );
                    try {
                        LayeredGraphNode graph = r.createRandomNode( null, 0, true );
                        SweepCrossingMinimizer cminzer = new SweepCrossingMinimizer();
                        for( int i = 0; i < 10; i++ )
                          cminzer.minimizeCrossings( graph );
                        SimpleNodePlacement.placeNodes( graph );
                        new MainView( graph );
                        setVisible( false );
                    } catch( Exception e1 )
                    {
                        JOptionPane.showMessageDialog(null, e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            }
            
        });
        add( gen, c );
        setSize( 270, 220 );
        setLocation( Toolkit.getDefaultToolkit().getScreenSize().width / 2 - getWidth() / 2, Toolkit.getDefaultToolkit().getScreenSize().height / 2 - getHeight() / 2 );
    }
}
