/Users/petercappello/NetBeansProjects/56-2014/56-2014-1-Clique/src/clique/Clique.java
package clique;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

/**
 *
 * @author Peter Cappello
 */
public class Clique 
{    
    /* If Clique is used by other classes, these attributes may best be thought 
     * of as NOT being attributes of Clique.
     */
    private static final int IMAGE_SIZE = 800; // units: pixels
    private static final int BORDER_SIZE = IMAGE_SIZE / 100; // units: pixels
    private final Image image;
    private final ImageIcon imageIcon;
    private final JLabel jLabel;
    private final JFrame jFrame;
    
    // image parameters
    private final int nNodes;          // # of nodes in the clique 
    private final int nodeDiameter;    // of circle representing a node (pixels)
    private final int cliqueRadius;    // (pixels)
    private final double angularDelta; // (radians)
    
    Clique()
    {
        image = new BufferedImage( IMAGE_SIZE, IMAGE_SIZE, BufferedImage.TYPE_INT_ARGB );
        imageIcon = new ImageIcon( image );
        jLabel = new JLabel( imageIcon );
        jFrame = new JFrame( "Clique" );
        jFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        Container container = jFrame.getContentPane();
        container.setLayout( new BorderLayout() );
        container.add( jLabel, BorderLayout.CENTER );
        jFrame.pack();
        
        // set image parameters
        nNodes = getInt( "What is the size of the clique [3 - 30]?" );
        nodeDiameter = IMAGE_SIZE / nNodes;
        cliqueRadius = ( IMAGE_SIZE - nodeDiameter ) / 2 - BORDER_SIZE;
        angularDelta = 2 * Math.PI / nNodes;
    }
    
    /**
     * @param args the command line arguments: Unused.
     */
    public static void main(String[] args) 
    {
        Clique clique = new Clique();
        clique.paint();
        clique.view();
    }
    
    private void view() { jFrame.setVisible( true ); }
    
    private int getInt( String promptString )
    {
        String intString = JOptionPane.showInputDialog( promptString );
        return Integer.parseInt( intString );
    }
        
    /**
     * Paint the clique representation onto the Image.
     */
    private void paint()
    {
        Graphics graphics = image.getGraphics();
        
        // paint edges
        for ( int startNode = 0; startNode < nNodes - 1; startNode++ )
        {          
            // compute coordinates of node1
            int x1Node = getNodeX( startNode );
            int y1Node = getNodeY( startNode );
            
            // get red component of edge color
            double thetaStartNode = getAngle( startNode );
            float redfraction = (float) Math.abs( Math.cos( thetaStartNode ) );
            
            for ( int stopNode = startNode + 1; stopNode < nNodes; stopNode++ )
            {
                 // compute coordinates of node2
                int x2Node = getNodeX( stopNode );
                int y2Node = getNodeY( stopNode );
                
                // compute & set line color
                double thetaStopNode = getAngle( stopNode );
                
                float blufraction = (float) Math.abs( Math.sin( thetaStopNode ) );
                graphics.setColor( new Color( redfraction, (float) 0.0, blufraction ) );
                graphics.drawLine( x1Node, y1Node, x2Node, y2Node );
            }
        }
        
        // paint nodes circles: ensures that circles obscure the part an edge that overlaps with the circle.
        for ( int startNode = 0; startNode < nNodes; startNode++ )
        {
            // compute coordinates of node
            int x1Node = getNodeX( startNode );
            int y1Node = getNodeY( startNode );
            
            // paint nodes
            graphics.setColor( Color.red );
            graphics.fillOval( x1Node - nodeDiameter / 2, y1Node - nodeDiameter / 2, nodeDiameter, nodeDiameter );
            graphics.setColor( Color.black );
            graphics.drawOval( x1Node - nodeDiameter / 2, y1Node - nodeDiameter / 2, nodeDiameter, nodeDiameter );
        }
    }
    
    private int getNodeX( double nodeNum ) 
    { 
        return IMAGE_SIZE / 2 + (int) ( cliqueRadius * Math.cos( angularDelta * nodeNum ) ) ;
    }
    
    private int getNodeY( double nodeNum ) 
    { 
        return IMAGE_SIZE / 2 - ( (int) ( cliqueRadius * Math.sin( angularDelta * nodeNum ) ) );
    }
    
    private double getAngle( int node ) { return 2.0 * Math.PI * node / nNodes; }
}