import java.awt.*;

import javax.swing.*;
import java.util.*;
import java.util.List; // don't want java.awt.List


/**
 * RLabel is a text label that can be rotated to any angle.
 * Angles are measured in radians.  Angle 0 points along
 * the positive X axis, and increasing angles turn toward
 * the positive Y axis (clockwise).  For example,
 * angle pi/4 produces downward-sloping text, while
 * angle -pi/4 produces upward-sloping text.
 * <p>
 * Rotation occurs around the center of the label, and
 * the text of the label is centered in this component's
 * bounding box.
 * <p>
 * The text label may include HTML tags, in the manner of JLabel.
 * HTML tags are only interpreted if the tag begins with &lt;html&gt;. 
 */
public class RLabel extends JComponent {
    
    // JLabel that we'll delegate to for
    // bounding box computations and painting.
    private JLabel label;
    
    /**
     * Make an RLabel.
     * @param text text for label
     * @param angle rotation angle, measured in radians clockwise from
     * the positive x axis
     */
    public RLabel(String text, double angle) {
        label = new JLabel(text);
	label.setFont(new Font("SansSerif", Font.PLAIN, 12));

        // For debugging purposes: make the
        // bounding box of the text visible as
        // a filled orange rectangle.
        label.setBackground(Color.orange);
        label.setOpaque(true);
        
        updateSizes();
    }
    
    /**
     * Get the text of this label.
     * @return text of label
     */
    public String getText(){
        return null;
    }
    
    /**
     * Set the text of this label.
     * @param text new text for label.  May contain HTML tags for
     * formatting.
     */
    public void setText(String text) {
    }
    
    /**
     * Get the rotation angle of this label.
     * @return angle of rotation, measured in radians clockwise from
     * the positive x axis
     */
    public double getAngle() {
        return 0;
    }
    
    /**
     * Set the rotation angle of this label.
     * @param angle new angle, measured in radians clockwise from
     * the positive x axis
     */
    public void setAngle(double angle) {
    }
    
    /*
     * Update bounding boxes of this RLabel 
     * and its JLabel delegate.
     */
    private void updateSizes() {
        Dimension pref = label.getPreferredSize();
        
        // Tell JLabel that it can draw itself full size.
        // If we fail to do this, the JLabel will think it's
        // 0 width, 0 height by default, so it won't
        // do anything when we try to paint it.
        label.setSize(label.getPreferredSize());
        
        // Tell our layout manager what our preferred
        // size is.  Layout manager will be responsible
        // for setting our actual size.
        setPreferredSize(pref);
        
        // We should update our minimum size and maximum size
        // in the same way, but JLabels typically don't have
        // min or max size, so let's not bother with that for
        // now.
    }
    
    /**
     * Paint this RLabel.
     * @param g Graphics to paint on
     */
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        Graphics2D g2 = (Graphics2D) g;

        // turn on antialiasing
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);

        // paint the label
        label.paint(g2);
    }
    
    /**
     * Test RLabel by displaying a rotated label in a window.
     * @param args command line arguments.  args[0] is the initial angle of
     * the label in integer DEGREES.  If no arguments are specified, the
     * initial angle is 45 degrees.
     */
    public static void main(String[] args) {
        int degrees = (args.length > 0) ? Integer.parseInt(args[0]) : 45;
        double angle = degrees * Math.PI/180;

        JFrame f = new JFrame("The Second Coming (by William Butler Yeats)");
        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
        
        Container c = f.getContentPane();        
        RLabel label = new RLabel(
                "<html><center><font size=5>"
                   +  "Turning and turning in the widening gyre<br>"
                   +  "The falcon cannot hear the falconer;<br>"
                   +  "Things fall apart; the centre cannot hold;<br>"
                   +  "Mere anarchy is loosed upon the world,<br>"
                   +  "The blood-dimmed tide is loosed, and everywhere<br>"
                   +  "The ceremony of innocence is drowned;<br>"
                   +  "The best lack all conviction, while the worst<br>"
                   +  "Are full of passionate intensity."
                   +  "</font></center></html>",

                angle
        );        
        c.add(label, BorderLayout.CENTER);
        
        f.pack();
        f.show();
    }    
}
