import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

public class ZSquaredImage extends JPanel  {
    int mode;
    static final int circle = 0;
    static final int quadratic = 1;
    public ZSquaredImage(int m) {
	mode = m;
        setBackground(Color.white);
    }    
    
    public void paintComponent(Graphics gfx) {
        super.paintComponent(gfx);
        Graphics2D g = (Graphics2D) gfx;
	g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
			   RenderingHints.VALUE_ANTIALIAS_ON);

	Rectangle bounds = getBounds();
	double scale = 35;
	double maxY = bounds.height/(2*scale);
	double maxX = bounds.width/(2*scale);
	AffineTransform transform = new AffineTransform();
	transform.scale(scale, scale);
	transform.translate(maxX, maxY);
	transform.scale(1, -1);

	GeneralPath grid = new GeneralPath();
	for (int i = (int)Math.floor(-maxX); i <= maxX; i++) {
	    grid.moveTo(i, (float) maxY);
	    grid.lineTo(i, (float) -maxY);
	}
	for (int j = (int)Math.floor(-maxY); j <= maxY; j++) {
	    grid.moveTo((float)-maxX, j);
	    grid.lineTo((float) maxX, j);
	}
	g.setPaint(Color.lightGray);
	g.draw(transform.createTransformedShape(grid));

	GeneralPath axes = new GeneralPath();
	axes.moveTo(0, (float)-maxY);
	axes.lineTo(0, (float) maxY);
	axes.moveTo((float)-maxX, 0);
	axes.lineTo((float) maxX, 0);
	g.setPaint(Color.black);
	g.draw(transform.createTransformedShape(axes));
	
	Ellipse2D.Double circle = new Ellipse2D.Double(0, -1, 2, 2);
	g.setPaint(new Color(0.5f, 0.5f, 1f));
	g.setStroke(new BasicStroke(2f));
	g.draw(transform.createTransformedShape(circle));

	GeneralPath fcircle = new GeneralPath();
	float[] fz = zsquared(2,0);
	fcircle.moveTo(fz[0], fz[1]);
	int steps = 100;
	double dtheta = 2*Math.PI/steps;
	double theta = 0;
	for (int i = 1; i < steps; i++) {
	    theta += dtheta;
	    fz = zsquared(1 + Math.cos(theta), Math.sin(theta));
	    fcircle.lineTo(fz[0], fz[1]);
	}
	fcircle.closePath();
	g.setPaint(new Color(1f, 0.5f, 0.5f));
	g.setStroke(new BasicStroke(2f));
	g.draw(transform.createTransformedShape(fcircle));
	
	
    }

    public float[] zsquared(double x, double y) {
	return new float[] { (float)(x*x - y*y), (float)(2*x*y) };
    }

    public static void main(String[] args) {
	int mode = circle;
	try {
	    mode = Integer.parseInt(args[6]);
	} catch(Exception ex) {}
        ZSquaredImage image = new ZSquaredImage(mode);

        JFrame frame = new JFrame("ZSquaredImage");
	frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(image, BorderLayout.CENTER);
        image.setPreferredSize(new Dimension(300, 300));
        frame.pack();
        frame.setVisible(true);
    }
}
