/*
 * @(#)ActivityIcon.java     1.0  16 September 2004
 *
 * Copyright 2004
 * College of Computer and Information Science
 * Northeastern University
 * Boston, MA  02115
 *
 * The Java Power Tools software may be used for educational
 * purposes as long as this copyright notice is retained intact
 * at the top of all source files.
 *
 * To discuss possible commercial use of this software, 
 * contact Richard Rasala at Northeastern University, 
 * College of Computer and Information Science,
 * 617-373-2462 or rasala@ccs.neu.edu.
 *
 * The Java Power Tools software has been designed and built
 * in collaboration with Viera Proulx and Jeff Raab.
 *
 * Should this software be modified, the words "Modified from 
 * Original" must be included as a comment below this notice.
 *
 * All publication rights are retained.  This software or its 
 * documentation may not be published in any media either
 * in whole or in part without explicit permission.
 *
 * This software was created with support from Northeastern 
 * University and from NSF grant DUE-9950829.
 */

package edu.neu.ccs.jpf;

import edu.neu.ccs.util.*;

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

/**
 * <P>Provides <CODE>JComponent</CODE>s that display icons 
 * for the input, action, and output displays 
 * in <CODE>MethodGUI</CODE>.</P>
 *
 * @author Richard Rasala
 * @version 2.3.2
 * @since 2.2
 */
class ActivityIcon {

    /** Color of input arrow. */
    protected static Color inputColor  = Color.green;
    
    /** Color of action arrow. */
    protected static Color actionColor = Color.yellow;
    
    /** Color of output arrow. */
    protected static Color outputColor = Color.red;
    
    /** Color of the box. */
    protected static Color boxColor    = Color.black;
    
    /** The box size. */
    private static int boxsize = 24;
    
    /** Half of the box size. */
    private static int halfsize = boxsize / 2;
    
    /** The line width. */
    private static int linewidth = 4;
    
    /** Half of the line width. */
    private static int halfwidth = linewidth / 2;
    
    /** The arrow size. */
    private static int arrowsize = 4;
    
    /** The component width. */
    private static int width = 2 * (arrowsize + boxsize);
    
    /** The component height. */
    private static int height = boxsize;
    
    /** The box x-corner. */
    private static int boxXCorner = arrowsize + halfsize;
    
    /** The box y-corner. */
    private static int boxYCorner = 0;
    
    /** The box x-center. */
    private static int boxXCenter = arrowsize + boxsize;
    
    /** The box y-center. */
    private static int boxYCenter = halfsize;
    
    /* The common shape for the box. */
    private static Rectangle2D.Double box =
        new Rectangle2D.Double(boxXCorner, boxYCorner, boxsize, boxsize);
    
    /** The start x-position for the input line. */
    private static int xInput = arrowsize + halfwidth;
    
    /** The final x-position for the output line. */
    private static int xOutput = width - xInput;
    
    /** The start and final y-position for both lines. */
    private static int yCommon = halfwidth;
    
    /** The arc inset. */
    private static int arcInset = 2;
    
    /** The arc box x-corner. */
    private static int arcXCorner = boxXCorner + arcInset + halfwidth;
    
    /** The arc box y-corner. */
    private static int arcYCorner = boxYCorner + arcInset + halfwidth;
    
    /** The arc diameter. */
    private static int arcDiameter = boxsize - linewidth - 2 * arcInset;
    
    /** The arc start angle. */
    private static int arcStartAngle = 135;
    
    /** The arc total angle. */
    private static int arcTotalAngle = 315;
    
    /** The arc radius. */
    private static int arcRadius = arcDiameter / 2;
    
    /** The side of a 45-45-90 right triangle with hypotenuse equal to the arc radius. */
    private static int side = (int) Math.round(arcRadius * MathUtilities.sindeg(45));
    
    /** The x-position of the start of the arc. */
    private static int arcXStart = boxXCenter - side;
    
    /** The y-position of the start of the arc. */
    private static int arcYStart = boxYCenter - side;
    
    
    /** 
     * Icon representing an input parameter. 
     *
     * @author Richard Rasala
     * @version 2.3.2
     * @since 2.2
     */
    public static class InputIcon extends JComponent {
        
        public InputIcon() {
            setPreferredSize(new Dimension(width, height));
        }
        
        protected void paintComponent(Graphics g) {
            
            Line2D.Double line = new Line2D.Double();
            
            Graphics2D g2 = (Graphics2D)g;
            
            g2.setStroke
                (new BasicStroke
                    (linewidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            
            g2.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            
            // draw the box
            if (boxColor == null)
                boxColor = Color.black;
            
            g2.setPaint(boxColor);
            g2.fill(box);
            
            // draw the arrow segments
            if (inputColor == null)
                inputColor = Color.red;
            
            g2.setPaint(inputColor);
            
            // the line down
            line.setLine(xInput, yCommon, xInput, boxYCenter);
            g2.draw(line);
            
            // the line into the box
            line.setLine(xInput, boxYCenter, boxXCenter, boxYCenter);
            g2.draw(line);
            
            // the arrow head
            line.setLine
                (boxXCenter, boxYCenter, boxXCenter - arrowsize, boxYCenter - arrowsize);
            g2.draw(line);
            
            line.setLine
                (boxXCenter, boxYCenter, boxXCenter - arrowsize, boxYCenter + arrowsize);
            g2.draw(line);
        }
        
    }
    
    
    /** 
     * Icon representing execution of an action. 
     *
     * @author Richard Rasala
     * @version 2.3.2
     * @since 2.2
     */
    public static class ActionIcon extends JComponent {
        
        public ActionIcon() {
            setPreferredSize(new Dimension(width, height));
        }
        
        protected void paintComponent(Graphics g) {
            Arc2D.Double arc = new Arc2D.Double();
            Line2D.Double line = new Line2D.Double();
            
            Graphics2D g2 = (Graphics2D)g;
            
            g2.setStroke
                (new BasicStroke
                    (linewidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            
            g2.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            
            // draw the box
            if (boxColor == null)
                boxColor = Color.black;
            
            g2.setPaint(boxColor);
            g2.fill(box);
            
            // draw the arrow segments
            if (actionColor == null)
                actionColor = Color.yellow;
            
            g2.setPaint(actionColor);
            
            // the arc
            arc.setArc
                (arcXCorner, arcYCorner, arcDiameter, arcDiameter,
                 arcStartAngle, arcTotalAngle, Arc2D.OPEN);
            
            g2.draw(arc);
            
            // the arrow head horizontal
            line.setLine(arcXStart, arcYStart, arcXStart - arrowsize, arcYStart);
            g2.draw(line);
            
            // the arrow head "vertical"
            // arcXStart + 1 is used because it visually looks better!
            line.setLine(arcXStart, arcYStart, arcXStart + 1, arcYStart + arrowsize);
            g2.draw(line);
        }
        
    }
    
    
    /** 
     * Icon representing output.
     *
     * @author Richard Rasala
     * @version 2.3.2
     * @since 2.2
     */
    public static class OutputIcon extends JComponent {
        
        public OutputIcon() {
            setPreferredSize(new Dimension(width, height));
        }
        
        protected void paintComponent(Graphics g) {
            
            Line2D.Double line = new Line2D.Double();
            
            Graphics2D g2 = (Graphics2D)g;
            
            g2.setStroke
                (new BasicStroke
                    (linewidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            
            g2.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            
            // draw the box
            if (boxColor == null)
                boxColor = Color.black;
            
            g2.setPaint(boxColor);
            g2.fill(box);
            
            // draw the arrow segments
            if (outputColor == null)
                outputColor = Color.red;
            
            g2.setPaint(outputColor);
            
            // the line out of the box
            line.setLine(boxXCenter, boxYCenter, xOutput, boxYCenter);
            g2.draw(line);
            
            // the line up
            line.setLine(xOutput, boxYCenter, xOutput, yCommon);
            g2.draw(line);
            
            // the arrow head
            line.setLine
                (xOutput, yCommon, xOutput - arrowsize, yCommon + arrowsize);
            g2.draw(line);
            
            line.setLine
                (xOutput, yCommon, xOutput + arrowsize, yCommon + arrowsize);
            g2.draw(line);
        }
    }
}

